Static keyword in an array function parameter declaration

Here is an example where static actually makes a difference:

unsigned foo(unsigned a[2])
{
    return a[0] ? a[0] * a[1] : 0;
}

clang (for x86-64, with -O3) compiles this to

foo:
        mov     eax, dword ptr [rdi]
        test    eax, eax
        je      .LBB0_1
        imul    eax, dword ptr [rdi + 4]
        ret
.LBB0_1:
        xor     eax, eax
        ret

But after replacing the function parameter with unsigned a[static 2], the result is simply

foo:
        mov     eax, dword ptr [rdi + 4]
        imul    eax, dword ptr [rdi]
        ret

The conditional branch is not necessary because a[0] * a[1] evaluates to the correct result whether a[0] is zero or not. But without the static keyword, the compiler cannot assume that a[1] can be accessed, and thus has to check a[0].

Currently only clang does this optimization; ICC and gcc produce the same code in both cases.


This isn't used much by compilers in my experience, but one use is that the compiler can assume that the (array decayed into pointer) parameter is not NULL.

Given this function, both gcc and clang (x86) produce identical machine code at -O3:

int func (int a[2])
{
  if(a)
    return 1;
  return 0;
}

Disassembly:

func:
        xor     eax, eax
        test    rdi, rdi
        setne   al
        ret

When changing the parameter to int a[static 2], gcc gives the same output as before, but clang does a better job:

func: 
        mov     eax, 1
        ret

Since clang realizes that a can never be NULL, so it can skip the check.