首页 > 解决方案 > 获取条件表达式的地址

问题描述

我有以下代码:

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))" 不是?两者都涉及返回条件表达式的地址。

标签: cpointersconditional-operator

解决方案


&(X(a, s))中,&适用于((struct S*)(a, &s : 0))。该表达式的类型是struct S*,它是一个值(指向 a 的指针的值struct S)。&可能不适用于不是左值的值。1

&(X(a, s)->x)中,&适用于((struct S*)(a, &s : 0))->x。该表达式接受一个指向 a 的指针struct S并使用它来引用成员x,即 a int。它是一个左值,因为它指定了int作为成员的对象x(C 2018 6.5.2.3 4 明确表示结果->是一个左值)。由于它是一个左值,&因此可以应用于它。

脚注

1根据 C 2018 6.5.3.2 1,地址运算符&必须应用于函数指示符、[ ]或一元的结果或*指定不是位域且未用 声明的对象的左值register


推荐阅读