Skip to content

Use static in array declarators in function parameters if possible#123

Draft
MisterDA wants to merge 1 commit intotrunkfrom
static-array-declarator
Draft

Use static in array declarators in function parameters if possible#123
MisterDA wants to merge 1 commit intotrunkfrom
static-array-declarator

Conversation

@MisterDA
Copy link
Owner

This is a C99 feature that helps with static analysis.

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.

See Array declarators and Function declarators from the C standard.

It is not supported by MSVC: C11: static inside array parameter square brackets.

Both gcc and clang warn if NULL or if an array too small is passed to the function. Interestingly gcc also warns in the non-static case if an array too small is passed. cppcheck considers in both cases that the array has a fixed size and warns for out-of-bounds accesses.

Details
void f(int a[10]);
void g(int a[static 10]);
void h(int a[static 10]) {
    a[42] = 42;
}

void m(void) {
    int a[8];
    int b[11];

    f(0);
    f(a);
    f(b);

    g(0);
    g(a);
    g(b);
}
$ /opt/homebrew/Cellar/gcc/14.2.0_1/bin/gcc-14  -O0 -Wall -Wextra -D_FORTIFY_SOURCE=3 -c test.c
test.c: In function 'm':
test.c:15:5: warning: argument 1 null where non-null expected [-Wnonnull]
   15 |     g(0);
      |     ^
test.c:2:6: note: in a call to function 'g' declared 'nonnull'
    2 | void g(int a[static 10]);
      |      ^
test.c:12:5: warning: 'f' accessing 40 bytes in a region of size 32 [-Wstringop-overflow=]
   12 |     f(a);
      |     ^~~~
test.c:12:5: note: referencing argument 1 of type 'int[10]'
test.c:1:6: note: in a call to function 'f'
    1 | void f(int a[10]);
      |      ^
test.c:16:5: warning: 'g' accessing 40 bytes in a region of size 32 [-Wstringop-overflow=]
   16 |     g(a);
      |     ^~~~
test.c:16:5: note: referencing argument 1 of type 'int[10]'
test.c:2:6: note: in a call to function 'g'
    2 | void g(int a[static 10]);
      |      ^
$ /opt/homebrew/Cellar/llvm/19.1.2/bin/clang -O0 -Wall -Wextra -D_FORTIFY_SOURCE=3 -c test.c
test.c:15:5: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
   15 |     g(0);
      |     ^ ~
test.c:2:12: note: callee declares array parameter as static here
    2 | void g(int a[static 10]);
      |            ^~~~~~~~~~~~
test.c:16:5: warning: array argument is too small; contains 8 elements, callee requires at least 10 [-Warray-bounds]
   16 |     g(a);
      |     ^ ~
test.c:2:12: note: callee declares array parameter as static here
    2 | void g(int a[static 10]);
      |            ^~~~~~~~~~~~
2 warnings generated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant