Question

A very simple program in C:

#include <stdio.h>
#include <stdlib.h>

void process(int array[static 5]){
    int i;
    for(i=0; i<5; i++)
        printf("%d ", array[i]);
    printf("\n");
}

int main(){

    process((int[]){1,2,3});
    process(NULL);

    return 0;
}

I compile it: gcc -std=c99 -Wall -o demo demo.c

It does compile and when I run it, it crashes (quite predictable).

Why? What is the purpose of the static keyword in array parameter (whats the name of this construct btw?) ?

Was it helpful?

Solution

The static there is an indication (a hint — but not more than a hint) to the optimizer that it may assume there is a minimum of the appropriate number (in the example, 5) elements in the array (and therefore that the array pointer is not null too). It is also a directive to the programmer using the function that they must pass a big enough array to the function to avoid undefined behaviour.

ISO/IEC 9899:2011

§6.7.6.2 Array declarators

Constraints
¶1 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.

§6.7.6.3 Function declarators (including prototypes)

¶7 A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. 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.


Your code crashes because if you pass a null pointer to a function expecting an array (that is guaranteed to be the start of an array of 5 elements). You are invoking undefined behaviour and crash is an eminently sensible way of dealing with your mistake.

It is more subtle when you pass an array of 3 integers to a function that's guaranteed an array of 5 integers; again, you invoke undefined behaviour and the results are unpredictable. A crash is relatively unlikely; spurious results are very probable.

In effect, the static in this context has two separate jobs — it defines two separate contracts:

  1. It tells the user of the function that they must provide an array of at least 5 elements (and if they do not, they will invoke undefined behaviour).
  2. It tells the optimizer that it may assume a non-null pointer to an array of at least 5 elements and it may optimize accordingly.

If the user of the function violates the requirements of the function, all hell may break loose ('nasal demons' etc; generally, undefined behaviour).

OTHER TIPS

Your code is correct (and actually recommended... see the C99, N1124/1256, clause 6.7.5.3-7 (see Jonathan's full text below):

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 error is that your array definition -- you allocate it to hold 3 elements, but then you call a function that requires five elements (via the [static 5]), triggering a crash.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top