什么`int const a `真正意味着什么?

考虑以下数组声明:

int const a[5]; 

从语言的语义角度来看,它是否完全等同于const int a[5] ? 假设是这种情况,两个声明基本上都会读作“ a是5个常量整数的数组 ”。

读取第一个声明的另一种方法是“ a是一个5个整数的常量数组 ”。

显然,这两个陈述逻辑上都暗示整个数组是不变的; 如果一个数组由5个常量整数组成,则整个数组是常量。 或者,如果整个数组是常量,那么它的所有值也是常量。

我知道“常量数组”的概念有点无意义,因为数组不是可修改的左值(也就是说,它们不能出现在赋值的左侧)。 但是,在这两种声明会产生不同行为的情况下是否存在?

( Cdecl.org拒绝将第一个声明作为语法错误,而大多数当前编译器都接受它。)

编辑:

链接的副本询问const的顺序是否对普通变量很重要。 对于数组,它有点混乱,所以我不认为这是重复的。

它完全等同于const int a[5]

是的。

读取第一个声明的另一种方法是“a是一个5个整数的常量数组”。

并不是的。 您的声明(如编写)专门将const应用于数组元素。 为了将const应用于数组本身(而不是将其应用于数组元素),你必须做类似的事情

 int (const a)[5]; 

但这种声明在C语法上是无效的。

可以通过中间typedef间接尝试将const应用于数组本身

 typedef int A[5]; const A a; 

但在这种情况下,根据语言规则, const限定符“通过”到数组元素,整个事物只相当于

 const int a[5]; 

再次注意, const A a; 上面不等于const int a[5]; 。 它实际上等同于前面提到的int (const a)[5]; (!)。 (这是偷偷摸摸int (const a)[5];过去编译器的防御的合法方式。)但是那个int (const a)[5]; 是非常短暂的 – 它立即转变为const int a[5]; 由编译器。

如果一个数组由5个常量整数组成,则整个数组是常量。 或者,如果整个数组是常量,那么它的所有值也是常量。

嗯,这不完全正确。 C语言确实区分了数组对象本身及其元素。 从概念上讲,这些是不同的实体。 例如,正如您自己所说,语言规范说数组是不可修改的左值 。 当然,这不会阻止数组元素可修改。

数组作为一个整体和单个数组元素之间的这种概念上的区别,结合const的“通过”行为正是导致以下不愉快情况的原因

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

即它打破了“正常”的const正确性规则,允许我们用T *值初始化const T *指针。 (C ++故意更新它的const-correctness规则,使上面的代码“按预期”运行,但C坚持拒绝它。)

我把它放在一起:

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

而gcc(4.1.2)吐出这个:

 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 

所以至少基于此,似乎没有任何区别。