Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: swallowed FLP31-C

...

Noncompliant Code Example

The header tgmath.h provides type-generic macros for math functions. Although most functions from the math.h header have a complex counterpart in complex.h, several functions do not. Calling any of the following type-generic functions with complex values results in undefined behavior.

Functions That Should Not Be Called with Complex Values

atan2erffdimfminilogbllroundlogbnextafterrinttgamma
cbrterfcfloorfmodldexplog10lrintnexttowardroundtrunc
ceilexp2fmafrexplgammalog1plroundremainderscalbn 
copysignexpm1fmaxhypotllrintlog2nearbyintremquoscalbln 

 

This noncompliant code example attempts to take the logarithm of a complex number, resulting in undefined behavior:

Code Block
bgColor#ffcccc
langc
#include <complex.h>
#include <tgmath.h>
 
void func(void) {
  double complex c = 2.0 + 4.0 * I;
  double complex result = log2(c);
}

Compliant Solution

This compliant solution ensures that the logarithm is applied only to the real part of the complex number:

Code Block
bgColor#ccccff
langc
#include <complex.h>
#include <tgmath.h>
 
void func(void) {
  double complex c = 2.0 + 4.0 * I;
  double complex result = log2(creal(c));
}

Noncompliant Code Example

In this noncompliant example, the C standard library function strchr() is called through the function pointer fp with incorrectly typed arguments. According to the C Standard, subclause 6.3.2.3, paragraph 8 [ISO/IEC 9899:2011],

...

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <string.h>

char *(*fp)();

int main(void) {
  const char *c;
  fp = strchr;
  c = fp('e', "Hello");
  printf("%s\n", c);
  return 0;
}

Noncompliant Code Example

In this noncompliant example, the pointer to the C standard library function strchr() is declared with the correct arguments. This code still exhibits the same undefined behavior, but most compilers will warn that the arguments passed to fp do not match its declaration.

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <string.h>

char *(*fp)(const char *, int);
int main(void) {
  const char *c;
  fp = strchr;
  c = fp('e', "Hello");
  printf("%s\n", c);
  return 0;
}

Compliant Solution

In this compliant solution, the function pointer fp is invoked with the correct number and type of arguments:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <string.h>

char *(*fp)(const char *, int);

int main(void) {
  const char *c;
  fp = strchr;
  c = fp("Hello",'e');
  printf("%s\n", c);
  return 0;
}

Noncompliant Code Example

In this noncompliant example, the function f() is defined to take an argument of type long but f() is called from another file with an argument of type int:

Code Block
bgColor#FFCCCC
langc
/* In another source file */
long f(long x) {
  return x < 0 ? -x : x;
}

/* In this source file, no f prototype in scope */
long f();
 
long g(int x) {
  return f(x);
}

Compliant Solution

In this compliant solution, the prototype for the function f() is included in the source file in the scope of where it is called, and the function f() is correctly called with an argument of type long:

...

Bibliography

[CVE]CVE-2006-1174
[ISO/IEC 9899:2011]Subclause 6.3.2.3, "Pointers"
Subclause 6.5.2.2, "Function Calls"
[IEEE Std 1003.1:2013]open()
[Spinellis 2006]Section 2.6.1, "Incorrect Routine or Arguments"

...