CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function
https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL50-CPP.+Do+not+define+a+C-style+variadic+function
Noncompliand example
dcl5001.cpp
// Noncompliand example
#include <cstdarg>
int add(int first, int second, ...) {
int r = first + second;
va_list va;
va_start(va, second);
while (int v = va_arg(va, int)) {
r += v;
}
va_end(va);
return r;
}
Compile and link
$ ../cppgl17.sh dcl5001
$ clang++ dcl5001.cpp -std=c++17
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)
$ g++-7 dcl5001.cpp -std=c++17
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
Add main and printf debug code.
dcl5001a.cpp
//Noncompliant Code Example
//https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682
#define msg "CERT C++ Rule 01. Declarations and Initialization (DCL) \n DCL50-CPP. Do not define a C-style variadic function, dcl5001.cpp Noncompliant code example"
#include <iostream>
#include <cstdarg>
int add(int first, int second, ...) {
int r = first + second;
std::cout<< "r="<<r<<" first="<<first<< " second="<<second << std::endl;
va_list va;
va_start(va, second);
while (int v = va_arg(va, int)) {
std::cout<< "r="<<r<<" v="<<v<< std::endl;
r += v;
}
va_end(va);
return r;
}
int main() {
int i=3, j=4, k=5;
std::cout<< "add(3,4)=" << add(i,j)<< std::endl;
std::cout<< "add(3,4,5)=" << add(i,j,k)<< std::endl;
std::cout<< msg << std::endl;
return EXIT_SUCCESS;
}
Compile and go
$ ../cppgl17.sh dcl5000
$ clang++ dcl5000.cpp -std=c++17
add(3,4)=r=7 first=3 second=4
r=7 v=259
r=266 v=8
r=274 v=-1600729224
r=-1600728950 v=64
r=-1600728886 v=-523249824
r=-2123978710 v=250617856
r=-1873360854 v=-523249800
r=1898356642 v=-523249824
r=1375106818 v=492148000
r=1867254818 v=-1607973280
r=259281538 v=5
r=259281543 v=3
259281546
add(3,4,5)=r=7 first=3 second=4
r=7 v=5
r=12 v=8
r=20 v=-1600729224
r=-1600729204 v=64
r=-1600729140 v=-523249824
r=-2123978964 v=250617856
r=-1873361108 v=-523249800
r=1898356388 v=-1607973280
r=290383108 v=-1607973280
r=-1317590172 v=-1607973280
r=1369403844 v=5
r=1369403849 v=3
r=1369403852 v=250622160
r=1620026012 v=-1607973280
12052732
CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function, dcl5001.cpp Noncompliant code example
$ g++-7 dcl5000.cpp -std=c++17
add(3,4)=r=7 first=3 second=4
r=7 v=4
r=11 v=-1600597112
r=-1600597101 v=-1600729224
r=1093640971 v=64
1093641035
add(3,4,5)=r=7 first=3 second=4
r=7 v=5
r=12 v=4
r=16 v=-1600729224
r=-1600729208 v=64
-1600729144
CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function, dcl5001.cpp Noncompliant code example
Compliant Code Example(1)
dcl5002.cpp
//Compliant Code Example
//https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682
#define msg "CERT C++ Rule 01. Declarations and Initialization (DCL) \n DCL50-CPP. Do not define a C-style variadic function dcl5002.cpp Compliant Code Example"
#include <iostream>
#include <type_traits>
template <typename Arg, typename std::enable_if<std::is_integral<Arg>::value>::type * = nullptr>
int add(Arg f, Arg s) {
return f + s;
}
template <typename Arg, typename... Ts, typename std::enable_if<std::is_integral<Arg>::value>::type * = nullptr>
int add(Arg f, Ts... rest) {
return f + add(rest...);
}
int main() {
std::cout<< "add(3,4)=" << add(3,4)<< std::endl;
std::cout<< "add(3,4,5)=" << add(3,4,5)<< std::endl;
std::cout<< msg << std::endl;
return EXIT_SUCCESS;
}
Compile and go
cppgl17.sh
$ ../cppgl17.sh dcl5002
$ clang++ dcl5002.cpp -std=c++17
add(3,4)=7
add(3,4,5)=12
CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function, dcl5002.cpp Compliant Code Example
$ g++-7 dcl5002.cpp -std=c++17
add(3,4)=7
add(3,4,5)=12
CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function, dcl5002.cpp Compliant Code Example
Compliant Code Example(2)
dcl5003.cpp
//Compliant Code Example
//https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682
#define msg "CERT C++ Rule 01. Declarations and Initialization (DCL) \n DCL50-CPP. Do not define a C-style variadic function dcl5003.cpp Compliant Code Example"
#include <iostream>
#include <type_traits>
template <typename Arg, typename... Ts, typename std::enable_if<std::is_integral<Arg>::value>::type * = nullptr>
int add(Arg i, Arg j, Ts... all) {
int values[] = { j, all... };
int r = i;
for (auto v : values) {
r += v;
}
return r;
}
int main() {
std::cout<< "add(3,4)=" << add(3,4)<< std::endl;
std::cout<< "add(3,4,5)=" << add(3,4,5)<< std::endl;
std::cout<< msg << std::endl;
return EXIT_SUCCESS;
}
Compile and go
$ ../cppgl17.sh dcl5003
$ clang++ dcl5003.cpp -std=c++17
add(3,4)=7
add(3,4,5)=12
CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function, dcl5003.cpp Compliant Code Example
$ g++-7 dcl5003.cpp -std=c++17
add(3,4)=7
add(3,4,5)=12
CERT C++ Rule 01. Declarations and Initialization (DCL)
DCL50-CPP. Do not define a C-style variadic function, dcl5003.cpp Compliant Code Example