使用带有 & 运算符的右值

问题描述

我一直在努力理解下面的 C 代码

struct s {
        char m1;
        char m2;
};

int  main()
{
    /* This will print 1 */
    printf("%d\n",&((struct s*)0)->m2);

}

下面的部分在稍微修改下似乎有点混乱:

&((struct s*)0)->m2

在编译和运行初始代码时,我得到 1 的答案,这是我希望得到的。

我通过将 &((struct s*)0)->m2 替换为 &((struct s*)0),然后我收到一条错误消息,提示“左值需要作为一元‘&’操作数”。

问题:在原始代码部分 &((struct s*)0)->m2 中,& 的参数不是右值吗?如果是这样,为什么它当时编译成功,而在修改&((struct s*)0)的情况下却没有?

解决方法

在这种情况下:

 &((struct s*)0)

& 的操作数是一个始终是右值的强制转换的结果。在这种情况下:

&((struct s*)0)->m2

& 的操作数是 -> 运算符的结果,它是一个左值,特别是命名字段。另请注意,此表达式的结果为 undefined behavior,因为 NULL 指针值正在通过 -> 运算符取消引用。