为什么这段代码的最后一行是用C(Visual Studio)编译和运行的?左边是int*,右边是int。类型不匹配,所以我认为这是一个错误。换句话说,数据值不应该与内存地址兼容。
int*
int
int x = 6; int* baz = &x; int* foo = &x; foo = baz; /* ok */ foo = *baz; /* ?? */
我以为它不会编译。
bjp0bcyl1#
MSVC does give a warning for this.您一定忽略了警告。使用/WX开关将警告提升为错误。C标准要求对此提供诊断消息,因为它违反了C 2018 6.5.16 1中简单赋值的约束:应满足以下条件之一:[list共六种情况,其中没有一种涉及将int值赋给指针]然而,即使是符合C标准的编译器也可以接受程序,即使是在对约束冲突发出诊断之后,1,这就是发生的事情。使用/WX可以防止这种情况。
/WX
1允许这样做,因为标准中没有反对的规则,脚注9说:...它[C实现]也可以成功地翻译一个无效的程序...
tv6aics12#
你可以把内存地址看作一个整数,执行foo = *baz和foo = 6是一样的。换句话说,你的整数指针foo现在指向内存地址0x6,这仍然可以编译,但是如果你试图解引用foo,你会遇到未定义的行为。
foo = *baz
foo = 6
foo
0x6
2条答案
按热度按时间bjp0bcyl1#
MSVC does give a warning for this.您一定忽略了警告。
使用
/WX
开关将警告提升为错误。C标准要求对此提供诊断消息,因为它违反了C 2018 6.5.16 1中简单赋值的约束:
应满足以下条件之一:
[list共六种情况,其中没有一种涉及将
int
值赋给指针]然而,即使是符合C标准的编译器也可以接受程序,即使是在对约束冲突发出诊断之后,1,这就是发生的事情。使用
/WX
可以防止这种情况。脚注
1允许这样做,因为标准中没有反对的规则,脚注9说:
...它[C实现]也可以成功地翻译一个无效的程序...
tv6aics12#
你可以把内存地址看作一个整数,执行
foo = *baz
和foo = 6
是一样的。换句话说,你的整数指针
foo
现在指向内存地址0x6
,这仍然可以编译,但是如果你试图解引用foo
,你会遇到未定义的行为。