Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In addition to optional type qualifiers and the keyword static, the [ and ] may delimit
an expression or *. If they delimit an expression (which specifies the size of an array), the
expression shall have an integer type. If the expression is a constant expression, it shall
have a value greater than zero. The element type shall not be an incomplete or function
type. The optional type qualifiers and the keyword static shall appear only in a
declaration of a function parameter with an array type, and then only in the outermost
array type derivation.

By the way, one thing that came up for me last week was that we probably ought to mention conformant array parameters. For example,Consequently, an array declaration that serves as a function argument may have an index that is a variable or an expression. This does not indicate that the argument indicates a VLA, as the array argument is demoted to a pointer. But it can be used by developers to indicate the expected bounds of the array. This information may be used by compilers, or it may be ignored. But such declarations are useful to other developers as they serve to document relationships between array sizes and other relevant variables. Furthermore, the information can also be used by static analysis tools.

Code Block
int f(size_t n, int a[n])

...

;  // documents a relationship between n and a

Standard Examples

Section 6.7.6.3 of C11 has several examples of conformant array parameters. Example 4 illustrates a variably modified parameter:

...

Noncompliant Code Example

This code example provides a function that wraps a call to the standard memset() function, and has a similar set of arguments. However, while this function clearly intends that p point to an array of at least n chars, this invariant is not explicitly documented.

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

Noncompliant Code Example

This doesn't compile because n is used before being declared.noncompliant code example attempts to document the relationship between the pointer and the size using conformant array parameters. However, the variable n is used as the index of the array declaration before n is itself declared. Consequently this code example is not standards-compliant, and will usually fail to compile.

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

Compliant Solution

This compliant solution declares the size variable before using it in the subsequent array declaration. Consequently this code complies with the standard 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], char v) {
  memset( p, v, n);
}

...