每个带有 "array of type" 的表达式在 C 中总是会被转换为 "pointer to array of type"

Every expression with "array of type" will always be converted to "pointer to array of type" in C

示例代码:

int a[10]={0};
a = (void *) 0; // error: assignment to expression with array type

根据6.5.1 Primary expressions

primary-expression:
 identifier
 constant
 string-literal
 ( expression )

6.3.2.1 Lvalues, arrays, and function designators

An lvalue is an expression with an object type or an incomplete type other than void; if an lvalue does not designate an object when it is evaluated, the behavior is undefined. When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

我们知道a(void *) 0都是左值表达式,a有一个数组类型。

如果我们看下面的定义:

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

看起来 a 的类型从 array of int 转移到 pointer to array of int,它变成了“可修改的左值”。但是我的 gcc 9.3.0 说:

error: assignment to expression with array type"

我很困惑。

您错过的部分是关于赋值运算符约束的第 6.5.16p2 节:

An assignment operator shall have a modifiable lvalue as its left operand

数组不是可修改的左值,因此将它放在赋值的左侧是违反约束的。

此外,(void *)0 不是左值,根据 6.5.4p5 的脚注 104:

A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to the unqualified version of the type.

Looks like type of a transfer from array of int to pointer to array of int, it becomes "modifiable lvalue".

不,不是。根据问题中已经包含的定义,a 被转换为“指向 int 类型的表达式,即 不是 左值。结果不是左值的后果之一是您不能分配给(整个)数组。

But my gcc 9.3.0 said:

error: assignment to expression with array type"

...这比“赋值给一个非左值的表达式”更容易理解。