问题描述
我一直在努力理解下面的 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 指针值正在通过 ->
运算符取消引用。