C99 has added static in a function parameter (only meaningful in the function definition, not declaration):
void func( int a[static 10] )
{
if ( a == NULL )
{ /* this branch can be optimized out */ }
printf("%d", a[-1]); /* causes UB */
}
However, its meaning is defined in C11 6.7.6.3/7 as a semantic, not a constraint, which means that the compiler should not issue a diagnostic if the function is called incorrectly. In fact the compiler must not abort compilation unless it can prove that UB is caused in all branches. For example:
int main()
{
func(NULL); // UB
int b[9];
func(b); // UB
}
Why did the Standard not make this a constraint (therefore requiring a diagnostic)?
Secondary question: why is static
ignored in the prototype (6.7.6.3/13), instead of being a part of the function signature? It seems misleading to allow the prototype to contain it but the function body doesn't, and vice versa.
Because violations cannot be detected at compile time in all cases.
For example, the argument could be a pointer to the initial element of an array allocated with malloc()
. The compiler cannot in general determine how big the array is. Nor, if the argument is a pointer object, can the compiler detect in general whether it's null.
The main purpose of this feature is not to enforce restrictions on calls, but to enable optimizations. The compiler may assume that the parameter points to the initial element of an array of the specified length. In some cases, this can enable better code generation.
But compilers certainly can issue non-fatal warnings for the cases they can detect. There is no implication in the standard that such warnings should not be issued.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With