What does int int a [5] mean?

Consider the following array declaration:

int const a[5]; 

From the semantic point of view of the language, is this exactly equivalent to const int a[5] ? Assuming this is so, both declarations will essentially read as "a is an array of 5 constant ints".

An alternative way to read the first declaration would be "a is a constant array of 5 integers."

Obviously, both statements logically mean that the entire array is constant; if the array consists of 5 constant ints, then the whole array is constant. Alternatively, if the entire array is constant, then all of its values ​​are also constant.

I know that the concept of a "constant array" is a little pointless, since arrays are not changed by lvalues ​​(that is, they cannot appear on the left side of the task). However, are there any circumstances in which these two ads will give different behavior?

( Cdecl.org rejects the first declaration as a syntax error, while most modern compilers accept it.)

EDIT:

A linked duplicate asks if the order of const matters for ordinary variables. With arrays, this is a bit more confusing, so I don't consider this a duplicate.

+3
source share
2 answers

it is exactly equivalent to const int a[5]

Yes it is.

An alternative way to read the first declaration would be "a is a constant array of 5 integers."

Not really. Your declaration, as written, applies to elements of the const array. To apply const to the array itself (as opposed to applying it to the elements of the array), you will need to do something like

 int (const a)[5]; 

but such an expression is syntactically invalid in C.

An indirect attempt to apply const to the array itself can be done using an intermediate typedef

 typedef int A[5]; const A a; 

but in this case, in accordance with the rules of the language, the const qualifier "fails" to the elements of the array, and all this is simply equivalent

 const int a[5]; 

Note again that const A a; the above is not immediately equivalent to const int a[5]; . This is actually equivalent to the above int (const a)[5]; (!). (This is a legitimate way to steal int (const a)[5]; past compiler protections.) But this is int (const a)[5]; very short - it is immediately converted to const int a[5]; the compiler.

if the array consists of 5 constant ints, then the whole array is constant. Alternatively, if the entire array is constant, then all of its values ​​are also constant.

Well, that’s not entirely true. The C language distinguishes between an array object and its elements. Conceptually, these are different entities. For example, as you yourself noted, the language specification says that arrays are not changed by lvalues. This, of course, does not prevent the modification of array elements.

This conceptual difference between the array as a whole and the individual elements of the array in combination with the "failing" behavior for const is precisely what leads to the following unpleasant situation

 typedef int A[5]; A a; const A *p = &a; // ERROR!!! 

i.e. it violates the β€œnormal” const-correctness rule, which allows us to initialize const T * pointers using T * values. (C ++ deliberately updated the constant-correctness rules to make the above code behave "as expected", but C insists on its rejection.)

+12
source

I put this together:

 #include <stdio.h> int main() { int const a[5]; const int b[5]; int c[5]; a[0] = 1; b[0] = 2; c = a; c = b; } 

And gcc (4.1.2) spat it out:

 gcc -o /tmp/x2 /tmp/x2.c /tmp/x2.c: In function 'main': /tmp/x2.c:9: error: assignment of read-only location /tmp/x2.c:10: error: assignment of read-only location /tmp/x2.c:11: error: incompatible types in assignment /tmp/x2.c:12: error: incompatible types in assignment 

So, at least on the basis of this, there is no difference.

+1
source

All Articles