C 中对左值的要求
Requirements for lvalue in C
What are rvalues, lvalues, xvalues, glvalues, and prvalues? 中对左值有相当广泛的描述,但这是针对 C++ 的,我认为其中很多不适用于 C。
我对左值的理解如下:
数组不是,但它们的下标值可能是,只要那些不是数组。例如:
int arr[3][2];
arr // no --> int[3][2]
arr[1] // no --> int[2]
arr[1][1] // yes --> int
结构可以直接或通过成员访问,例如 .
或 ->
,只要它们不计算为数组即可。例如:
struct Member {int id};
Member member = {.id=2}, *member_ptr = &member;
member = {.id=3}; // ok
member_ptr = &member; // ok
member.id=3; // ok
member_ptr->id=4; // ok
address-of &
运算符不能。例如:
a = 7;
b = &a;
&b = &a; // invalid
*
运算符的值只要不引用数组即可。
int x[2][2] = {{1,2}, {3,4}};
*(x+1)=3; // not ok, evaluates to x[2]
*(*(x+1)+1) = 3; // ok
除了 7=x
等更明显的情况外,我的理解中是否遗漏了主要项目?或者上面有什么不正确的项目?
C standard在6.3.2.1p1节中定义了一个左值如下:
An lvalue is an expression (with an object type other than void
) that potentially designates an object; 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.
此定义包括数组,但数组不是可修改的左值。
间接运算符 *
的结果也是一个左值,因为它指向一个对象。如果结果对象是数组,这也适用。
数组下标运算符 []
也产生左值,因为 x[y]
完全等同于 *(x + y)
.
成员访问运算符.
和指向成员的指针运算符->
的结果也是一个左值。
复合文字也是左值。例如,以下是有效的:
int *p = (int [3]){1,2,3};
p[0] = 4;
What are rvalues, lvalues, xvalues, glvalues, and prvalues? 中对左值有相当广泛的描述,但这是针对 C++ 的,我认为其中很多不适用于 C。
我对左值的理解如下:
数组不是,但它们的下标值可能是,只要那些不是数组。例如:
int arr[3][2]; arr // no --> int[3][2] arr[1] // no --> int[2] arr[1][1] // yes --> int
结构可以直接或通过成员访问,例如
.
或->
,只要它们不计算为数组即可。例如:struct Member {int id}; Member member = {.id=2}, *member_ptr = &member; member = {.id=3}; // ok member_ptr = &member; // ok member.id=3; // ok member_ptr->id=4; // ok
address-of
&
运算符不能。例如:a = 7; b = &a; &b = &a; // invalid
*
运算符的值只要不引用数组即可。int x[2][2] = {{1,2}, {3,4}}; *(x+1)=3; // not ok, evaluates to x[2] *(*(x+1)+1) = 3; // ok
除了 7=x
等更明显的情况外,我的理解中是否遗漏了主要项目?或者上面有什么不正确的项目?
C standard在6.3.2.1p1节中定义了一个左值如下:
An lvalue is an expression (with an object type other than
void
) that potentially designates an object; 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.
此定义包括数组,但数组不是可修改的左值。
间接运算符 *
的结果也是一个左值,因为它指向一个对象。如果结果对象是数组,这也适用。
数组下标运算符 []
也产生左值,因为 x[y]
完全等同于 *(x + y)
.
成员访问运算符.
和指向成员的指针运算符->
的结果也是一个左值。
复合文字也是左值。例如,以下是有效的:
int *p = (int [3]){1,2,3};
p[0] = 4;