Is GCC right about this being a VLA?

141 Views Asked by At

This question is quite similar to "Are conformant array parameters VLAs?", with the only difference being that here I'm using the static keyword within the [ and ] of the array declaration (introduced in C99), meaning that the declared array should have space for at least len elements. Here's an example:

#include <stddef.h>
#include <stdio.h>

void print_array(size_t len, const int arr[static len]) {
    for (size_t i = 0; i < len; i++) {
        printf("%d\n", arr[i]);
    }
}

int main(void) {
    const int arr[] = {1, 2, 3, 4};
    print_array(sizeof arr / sizeof *arr, arr);
    return 0;
}

This code when compiled with the -Wvla flag on both GCC and Clang gives the following warning:

main.c:4:1: warning: ISO C90 forbids variable length array ‘arr’ [-Wvla]
    4 | void print_array(size_t len, const int arr[static len]) {
      | ^~~~

What would be the point in arr being a VLA even when specifying static? Wouldn't this make static useless for cases like this?

I tried looking for an answer in the C standard, but I was unable to find one.

Thanks!

1

There are 1 best solutions below

4
Eric Postpischil On BEST ANSWER

Is GCC right about this being a VLA?

C 2018 (and C 2011) 6.7.6.2 4 says, of array declarators:

… If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

In the declaration const int arr[static len], len is not an integer constant expression, so the array type is a variable length array type. So GCC is correct.

What would be the point in arr being a VLA even when specifying static?

6.7.6.3 7 says:

… 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.

An example of how a compiler could use this is that, if the body of the function contains an evaluated expression arr[i], where arr has been declared with const int array[static len], the compiler may presume i < len, and it could make optimizations based on that.

Wouldn't this make static useless for cases like this?

No, although it would not surprise me if a compiler does not take advantage of this information.