获取条件表达式的地址
Taking the address of a conditional expression
我有以下代码:
struct S {
int x;
};
#define X(a, s) ((struct S*)(a ? &s : 0))
int main(void)
{
int a;
struct S s;
struct S *t;
int *x;
a = 3;
s.x = 4;
x = &(X(a, s)->x);
t = &(X(a, s));
}
当我编译这个时,我在最后一行得到一个错误:
test.c: In function ‘main’:
test.c:18:9: error: lvalue required as unary ‘&’ operand
t = &(X(a, s));
^
为什么“&(X(a, s)->x)”是有效代码,而“&(X(a, s))”不是?两者都涉及返回条件表达式的地址。
在&(X(a, s))
中,&
应用于((struct S*)(a, &s : 0))
。该表达式的类型是 struct S*
,它是一个值(指向 struct S
的指针的值)。 &
不能应用于非左值的值。1
在&(X(a, s)->x)
中,&
应用于((struct S*)(a, &s : 0))->x
。该表达式采用指向 struct S
的指针,并使用它来引用成员 x
,这是一个 int
。它是一个左值,因为它指定了作为成员 x
的 int
对象(C 2018 6.5.2.3 4 明确表示 ->
的结果是一个左值)。由于它是左值,因此可以对其应用 &
。
脚注
1 Per C 2018 6.5.3.2 1,地址运算符 &
必须应用于函数指示符,[ ]
或一元的结果*
,或指定一个对象的左值,该对象不是 bit-field 且未使用 register
声明。
我有以下代码:
struct S {
int x;
};
#define X(a, s) ((struct S*)(a ? &s : 0))
int main(void)
{
int a;
struct S s;
struct S *t;
int *x;
a = 3;
s.x = 4;
x = &(X(a, s)->x);
t = &(X(a, s));
}
当我编译这个时,我在最后一行得到一个错误:
test.c: In function ‘main’:
test.c:18:9: error: lvalue required as unary ‘&’ operand
t = &(X(a, s));
^
为什么“&(X(a, s)->x)”是有效代码,而“&(X(a, s))”不是?两者都涉及返回条件表达式的地址。
在&(X(a, s))
中,&
应用于((struct S*)(a, &s : 0))
。该表达式的类型是 struct S*
,它是一个值(指向 struct S
的指针的值)。 &
不能应用于非左值的值。1
在&(X(a, s)->x)
中,&
应用于((struct S*)(a, &s : 0))->x
。该表达式采用指向 struct S
的指针,并使用它来引用成员 x
,这是一个 int
。它是一个左值,因为它指定了作为成员 x
的 int
对象(C 2018 6.5.2.3 4 明确表示 ->
的结果是一个左值)。由于它是左值,因此可以对其应用 &
。
脚注
1 Per C 2018 6.5.3.2 1,地址运算符 &
必须应用于函数指示符,[ ]
或一元的结果*
,或指定一个对象的左值,该对象不是 bit-field 且未使用 register
声明。