2017-06-22 29 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位。