Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is [static N] not enforced at compile-time?

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.

like image 785
M.M Avatar asked Mar 17 '15 03:03

M.M


1 Answers

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.

like image 192
Keith Thompson Avatar answered Oct 04 '22 17:10

Keith Thompson