在一些在 GCC 4.6(带有-fpermissive
)上编译良好的遗留代码中,我有这个:
uint16_t a = 0;
void* b = ...;
if(b == a) // ...
这种比较在 GCC 4.6 上是否定义明确?它是向下转换为 16 位还是向上转换为 32/64 位?
虽然这没有明确地写在 C++11 标准(N3337 草案)中,但我能够想出这个(强调我的)。
§5.9 关系运算符
可以比较指向相同类型的对象或函数的指针(指针转换后),结果定义如下
— 如果两个指针...
— 如果两个指针...
— 如果两个指针...
— 如果两个指针...
— 如果两个指针...
—未指定其他指针比较。
现在对于平等部分:
§5.10 等式运算符
==(等于)和 !=(不等于)运算符具有与关系运算符相同的语义限制、转换和结果类型,但它们的优先级较低和真值结果除外。
我相信这样的比较是不确定的。
看起来它向上转换了 16 位整数以匹配指针大小。运行以下代码输出"upcast"
uint16_t a = 1;
void* b = (void*)0x10001;
(b == a) ? printf("downcast") : printf("upcast");
它可能编译也可能不编译(不确定,这取决于编译器和编译器选项)在任何情况下,转换都将执行如下:
if( b == (void*)a )
{
}
请注意,向上转换/向下转换不是正确使用的词,因为它与类有关,在这种情况下只是类型转换。