2017-06-22 75 views
0
UINT One = 1; 
LONG  mylong  = LONG(-1) * One; 
LONGLONG mylonglong1 = LONG(-1) * One; 
LONGLONG mylonglong2 = LONG(LONG(-1) * One); 

保存在mylong,mylonglong1mylonglong2中的值是多少?从int到longlong的危险转换:没有警告?

mylong  = 0xffffffff   (ok) 
mylonglong1 = 0x00000000ffffffff (why?) 
mylonglong2 = 0xffffffffffffffff (ok) 

我真的很惊讶地知道的mylonglong1的结果,更惊讶的是,没有编译警告。

为什么将LONG分配给LONGLONG导致左填充为零?


到底发生在一个项目中使用函数CFile的一个问题:: SEEK()

virtual LONG Seek(LONG lOff, UINT nFrom); 

定义如下:https://msdn.microsoft.com/en-us/library/aa270542(v=vs.60).aspx 迁移到

virtual ULONGLONG Seek(LONGLONG lOff, UINT nFrom); 

这里定义https://msdn.microsoft.com/library/b2eb5757-d499-4e67-b044-dd7d1abaa0f8.aspx#cfile__seek

迁移后不长呃工作,因为lOff的参数转换没有给出预期的结果。

+1

你把SO与猜谜游戏网站混淆了吗?要知道答案,可以简单地运行代码并打印值,不是吗? – user463035818

+0

使用调试器来运行它有什么好处? – George

+0

由于大家都在抱怨问题的格式,而不是我重写的内容。希望它能够更好地适应现在的格式,并且会吸引正常的答案。 – CompuChip

回答

2

在表达(-1) * (UINT)1,第一操作数被根据operand conversion rules转换为UINT

否则,如果无符号的操作数的转换秩大于或等于所述符号操作数的转换等级,符号操作数是转换为无符号操作数的类型。

因此,我们有一个无符号乘法,结果类型为UINT。从UINTLONGLONG的转换是直接的,因为LONGLONG可以表示UINT可表示的每个数字,在这种情况下为0xffffffff。这就是你最终以0x00000000ffffffff

现在,当你做LONG(LONG(-1) * (UINT)1),上面的规则仍然适用,但你最终将无符号0xffffffff-1,然后把它登录扩展到LONGLONG

P.S:我假设Win32/Win64,其中UINT和LONG是32位,而LONGLONG是64位。