What does `int const a[5]` really mean?

Deadly 提交于 2019-12-20 02:05:12

问题


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.


回答1:


is it exactly equivalent to const int a[5]

Yes, it is.

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

Not really. Your declaration, as written, applies const to array elements specifically. In order to apply the const to the array itself (as opposed to applying it to the array elements), you'd have to do something like

int (const a)[5];

but such declaration is syntactically invalid in C.

An indirect attempt to apply const to the array itself can be made through an intermediate typedef

typedef int A[5];
const A a;

but in this case, per language rules, the const qualifier "falls through" to array elements and the whole thing is just equivalent to

const int a[5];

Note, again, that const A a; above is not immediately equivalent to const int a[5];. It is actually equivalent to the aforementioned int (const a)[5]; (!). (It is a legal way to sneak int (const a)[5]; past compiler's defenses.) But that int (const a)[5]; is very-short lived - it gets immediately transformed into const int a[5]; by the compiler.

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.

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 situation

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

i.e. it breaks the "normal" const-correctness rule that allows us to initialize const T * pointers with T * values. (C++ deliberately updated it const-correctness rules to make the above code to behave "as expected", but C insists on rejecting it.)




回答2:


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) spit out this:

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 based on this there doesn't appear to be any distinction.



来源:https://stackoverflow.com/questions/31412972/what-does-int-const-a5-really-mean

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!