Static hint in variable length arrays

I am a bit confused by the difference here on C99:

int myfunc (int array[n], int n) { ... } 

will not compile. As far as I know, you should always refer to the size of the array first, so you need to write it:

 int myfunc (int n, int array[n]) { ... } 

But if you put the static keyword, this works absolutely fine:

 int myfunc (int array[static 1], int n) { ... } 

This order, if I am much preferable, since I'm used to the fact that the first arrays come in the function call, but why is this possible?

Edit: realizing that the third example is not actually a VLA, it helps ...

For reference, this was a piece of code that I was considering, and this led to the question:

 int sum_array(int n, int m, int a[n][m]) { int i, j, sum = 0; for (i = 0; i < n; i++) for (j = 0; j < m; j++) sum += a[i][j]; return sum; } 
+4
source share
5 answers

Reason for which

 int myfunc (int n, int array[n]) { ... } 

and

 int myfunc (int array[n], int n) { ... } 

is not the result of lexical rules for defining area C. The identifier cannot be used before it is entered into the area. There are a few exceptions to this rule, but this is not one of them.

EDIT : here is the relevant paragraph of standard C:

(C99, 6.2.1p7) "Any other identifier has a scope that begins immediately after the completion of its declarator."

This rule also applies to declaring parameters in the function prototype area.

+8
source

The reason for the error has already been explained to you: you must declare n before you can use it in other declarations.

However, it is worth noting that none of these declarations actually declares variable-length arrays, as you seem to believe.

It is true that the syntax with [n] was first allowed in C99 and that it is formally a VLA declaration, but nevertheless, in this context, all these declarations declare array as an int * parameter, just as it always did in C89 / 90. Part [n] not a hint of any kind. The fact that you can use [n] in this declaration is indeed a side effect of VLA support, but any connection with VLA ends here. That [n] simply ignored.

The hint declaration requires the static inside [] . Thus, your declaration with [static 1] equivalent to the classic declaration of int array[1] (this means that 1 ignored, and the parameter is of type int * ), except that it gives the compiler a hint that there should not be less than element 1 in the memory location pointed to by array .

+2
source

This is because arrays must be declared with a constant value, so you cannot create an array using the size of a variable, and therefore cannot pass an array with a variable size. Also, if it's just a one-dimensional array, you don't need to pass a value at all, it's the transfer point in the second parameter to indicate the length of your array.

For this to work correctly, simply write the function header as follows:

 int myfunc (int myArray[], int n) {...} 

The order should not matter, but you cannot have the size of the array you pass in variables, it must be a constant value.

+1
source

If you use GCC and are ready to use some of your extensions, you can accomplish what you want here:

 int myFunc (int len; /* notice the semicolon!! */ int data[len], int len) { } 

The documentation for this extension (variable length arrays) is here .

Note that this extension is NOT available in clang for some reason, however I'm not quite sure why.

+1
source

EDIT: Derp, scope, of course.

My question is: why do you need this at all? You still get a pointer (you cannot pass arrays to a function in C, they degrade to a pointer, regardless of the signature of the function). This helps inform the caller of the expected input size, but is also useless. Since they already pass size, just use ...

 int myfunc(int arr[], size_t size) { // ... } 

or

 int myfunc(int *arr, size_t size) { // ... } 
0
source

All Articles