LoginSignup
0
0

More than 5 years have passed since last update.

CERTC++ Rule01 DCL50-CPP. Do not define a C-style variadic function

Last updated at Posted at 2018-04-22

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
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0