Issue 1070: Evaluation of [static] parameter array lengths

Authors: Joseph Myers
Date: 2026-05-28
Submitted against: C23
Status: Open
Cross-references: 0237, 1013

C23 6.7.7.4 specifies the meaning of static in parameter array declarators:

If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

The resolution to issue 0237 says that the largest size value specified by any declaration of that function using static in the program (not necessary visible at the call) is the one that applies. However, it is unclear what this means for declarations that are not definitions of the function, where a non-constant size expression is treated as replaced by * (note that [static *] is not valid syntax for an array declarator), because an expression only has a meaningful value if evaluated at some point in the execution of the program and there is no point at which such expressions are evaluated. This covers both obvious cases such as

void f(int n, int x[static n]);

from issue 0237 where the precise timing of evaluation may not be problematic, but also

void f(int n, int x[static ++n]);

where the side effects from evaluation of ++n do not occur, and block-scope declarations such as

void g()
{
  if (0)
    for (int m = 1; m < 10; m++) {
      void f(int x[static m]);
    }
}

where the static is meant to apply to all calls to f in the program, but execution never passes through the declaration so there is never a meaningful value of m.

Question 1

Is a length given with static in a parameter array declaration ever relevant in any context other than a declaration of a function with that parameter? Some examples of this, including cases where typeof or a typedef name are used in declaring a function rather than directly declaring it with a function declarator, are:

typeof (int (int n, int x[static n])) f1;
typedef int T(int n, int x[static n]);
T f2;
int (*p3)(int n, int x[static n]);

If it is ever relevant (contrary to the direction from issue 0237) then there would be issues with defining composite types, as well as the "same type" question from issue 1013 question 3.

Question 2

Is a length given with static that is not an integer constant expression, in a declaration of a function that is not a definition of that function (so considered to be replaced by *), ever relevant? If it is, when is the array length expression considered to be evaluated (taking into account that the expression may involve side effects and that objects referenced in that expression may not exist at the point of the call)?