Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: handle C94 too

...

Code Block
void addscalar(int n, int m, double a[n][n*m+300], double x);

int main(void) 
{
  double b[4][308];
  addscalar(4, 2, b, 2.17);
  return 0;
}

void addscalar(int n, int m, double a[n][n*m+300], double x) 
{
  for (int i = 0; i < n; i++)
  for (int j = 0, k = n*m+300; j < k; j++)
    /* a is a pointer to a VLA with n*m+300 elements */
    a[i][j] += x;
}

...

Code Block
bgColor#ffcccc
langc
void my_memset(char* p, size_t n, char v) 
{
  memset( p, v, n);
}

Noncompliant Code Example

...

Code Block
bgColor#ffcccc
langc
void my_memset(char p[n], size_t n, char v) 
{
  memset( p, v, n);
}

Compliant Solution (GCC)

This compliant solution declares uses a GNU extension to forward declare the size_t variable n before using it in the subsequent array declaration. Consequently, this code allows the existing parameter order to be retained and successfully documents the relationship between the array parameter and the size parameter.

Code Block
bgColor#ccccff
langc
void my_memset(size_t n; char p[n], size_t n, char v)
{
  memset(p, v, n);
}

Compliant Solution (API change)

This compliant solution changes the function's API by moving the size_t variable n to before the subsequent array declaration. Consequently, this code complies with the C99 standard and successfully documents the relationship between the array parameter and the size parameter, but requires all callers to be updated.

Code Block
bgColor#ccccff
langc
void my_memset(size_t n, char p[n], char v) 
{
  memset(p, v, n);
}

Exceptions

API05-C-EX0: The extended array syntax is not supported by C++, or platforms that do not support C99, such as MSVC. Consequently, C programs that must support such platforms, including Windows, need not use conformant array parameters. One option for portable code that must support MSVC such platforms is to use macros:

Code Block
bgColor#ccccff
langc
#include <stddef.h>
  
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || defined(_MSC_VER_STDC_NO_VLA__)
  #define N(x)
#else
  #define N(x)  (x)
#endif
  
int f(size_t n, int a[N(n)]);

...

Failing to specify conformant array dimensions increases the likelihood that another developer will invoke the function with out-of-range integers, which could cause an out-of-bounds memory read or write.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

API05-C

High

Probable

Medium

P12

L1

...

Bibliography

[ISO/IEC 9899:2011]Subclause 6.7.6.2, "Array Declarators"
Subclause 6.7.6.3, "Function Declarators (Including Prototypes)"

...