Consider the following array declaration:
int const a[5];
From the semantic standpoint of the language, is it exactly equivalent to const int a[5]
? Assuming that is the case, both declarations would essentially read like "a is an array of 5 constant ints".
The alternative way to read the first declaration would be "a is a constant array of 5 ints".
Obviously, both of the statements logically imply that the whole array is constant; if an array consists of 5 constant ints, then the entire array is constant. Alternatively, if the whole array is constant, then all of its values are also constant.
I am aware that the notion of a "constant array" is a bit meaningless since arrays are not modifiable lvalues (that is, they cannot appear on the left side of an assignment). However, are there any circumstances under which these two declarations would yield different behaviour?
(Cdecl.org rejects the first declaration as a syntax error, while most current compilers accept it.)
EDIT:
The linked duplicate asks whether the order of const
matters for ordinary variables. With arrays, it is a bit more confusing, so I don't consider this a duplicate.
I put this together:
And gcc (4.1.2) spit out this:
So at least based on this there doesn't appear to be any distinction.
Yes, it is.
Not really. Your declaration, as written, applies
const
to array elements specifically. In order to apply theconst
to the array itself (as opposed to applying it to the array elements), you'd have to do something likebut such declaration is syntactically invalid in C.
An indirect attempt to apply
const
to the array itself can be made through an intermediate typedefbut in this case, per language rules, the
const
qualifier "falls through" to array elements and the whole thing is just equivalent toNote, again, that
const A a;
above is not immediately equivalent toconst int a[5];
. It is actually equivalent to the aforementionedint (const a)[5];
(!). (It is a legal way to sneakint (const a)[5];
past compiler's defenses.) But thatint (const a)[5];
is very-short lived - it gets immediately transformed intoconst int a[5];
by the compiler.Well, that is not entirely true. C language does differentiate between the array object itself and its elements. Conceptually, these are different entities. For example, as you noted yourself, the language spec says that arrays are non-modifiable lvalues. This, of course, does not prevent array elements to be modifiable.
This conceptual distinction between array as a whole and individual array elements, combined with the "fall through" behavior for
const
is exactly what leads to the following unpleasant situationi.e. it breaks the "normal" const-correctness rule that allows us to initialize
const T *
pointers withT *
values. (C++ deliberately updated it const-correctness rules to make the above code to behave "as expected", but C insists on rejecting it.)