我使用Visual Studio 2010(cl.exe /W4)作为C文件编译此代码:
int main( int argc, char *argv[] )
{
unsigned __int64 a = 0x00000000FFFFFFFF;
void *orig = (void *)0xFFFFFFFF;
unsigned __int64 b = (unsigned __int64)orig;
if( a != b )
printf( " problem\ta: %016I64X\tb: %016I64X\n", a, b );
return;
}
Run Code Online (Sandbox Code Playgroud)
没有警告,结果是:
问题a:00000000FFFFFFFF b:FFFFFFFFFFFFFFFF
我想int orig = (int)0xFFFFFFFF不会引起争议,因为我没有指定一个整数的指针.但结果是一样的.
有人可以向我解释在C标准中它覆盖的orig是从0xFFFFFFFF扩展到0xFFFFFFFFFFFFFFFF的符号吗?
我原以为(unsigned __int64)orig会变成0x00000000FFFFFFFF.似乎转换首先是签名的__int64类型,然后它变为无符号?
编辑:这个问题已被回答,指针是符号扩展,这就是为什么我在gcc和msvc中看到这种行为.但是我不明白为什么当我做类似的事情时(unsigned __int64)(int)0xF0000000,符号扩展到0xFFFFFFFFF0000000,但是(unsigned __int64)0xF0000000没有显示我想要的是0x00000000F0000000.
编辑:上述编辑的答案.(unsigned __int64)(int)0xF0000000符号扩展的原因是因为,如用户R所述:
有符号类型(或任何类型)到无符号类型的转换 总是通过减少模1加上目标类型的最大值来进行.
并且在(unsigned __int64)0xF0000000 …