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; }
没有警告,结果是:
problem 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所述:
Conversion of a signed type (or any type) to an unsigned type
always takes place via reduction modulo one plus the max value of
the destination type.
并且在(无符号__int64)0xF0000000 0xF0000000作为无符号整数类型开始,因为它不能适合整数类型.接下来,已经无符号的类型转换为unsigned __int64.
因此,对我来说这是一个函数,它返回一个32位或64位指针作为无符号__int64进行比较我必须首先将32位应用程序中的32位指针转换为无符号类型,然后再将其提升为unsigned __int64.结果代码看起来像这样(但是,你知道,更好):
unsigned __int64 functionidontcontrol( char * ); unsigned __int64 x; void *y = thisisa32bitaddress; x = functionidontcontrol(str); if( x != (uintptr_t)y )
再次编辑:
这是我在C99标准中找到的:
6.3.1.3有符号和无符号整数
> 1当具有整数类型的值转换为另一个整数时
如果值可以由new表示,则为_Bool以外的类型
类型,它没有变化.
> 2否则,如果新类型是无符号的,则转换为
重复加或减一个以上的最大值
可以在新类型中表示,直到值在
新型的范围.49)
> 3否则,新类型已签名且值不可
代表其中;结果是实现定义的还是
提出了实现定义的信号.
> 49)规则描述了数学值的算术,而不是
给定类型表达式的值.