[英]Somewhat unexpected behaviour from left shift <<
這是當前在Windows 10上運行的32位MFC應用程序。已與Visual C ++ 2013一起編譯。
std::cout << "sizeof(long long) = " << sizeof(long long) << std::endl;
int rot{ 32 };
long long bits{ (1 << rot) };
std::cout << "bits with variable = " << bits << std::endl;
long long bits2 = (1 << 32);
std::cout << "bits2 with constant = " << bits2 << std::endl;
system("pause");
我在想,long long的大小是8個字節,足以管理我的32位。 這是調試版本的輸出:
sizeof(long long) = 8
bits with variable = 1
bits2 with constant = 0
Press any key to continue . . .
這是發行版本的輸出:
sizeof(long long) = 8
bits with variable = 0
bits2 with constant = 0
Press any key to continue . . .
因此,即使使用64位數據類型,顯然我的一位也被左移了。 但是我真的很困惑,如果將變量作為參數而不是常量進行移位,為什么調試版本會產生不同的輸出?
您需要64位的long long
類型。
表達式1 << 32
將使用操作數的int
類型進行計算,而與將結果分配給該變量的類型無關。
1LL << 32
和1LL << rot
將為您帶來更多運氣。 這導致使用long long
類型對表達式求值。
當前,您的程序的行為是不確定的,因為當您寫入1 << 32
時,您正在過度轉換類型。 還要注意, 1 << 32
是編譯時可評估的常量表達式,而1 << rot
不是。 這可能解釋了使用變量和常量之間觀察到的差異。
如果rot
是int
,則表達式1 << rot
將為您提供int
結果。 既然損壞已經造成(a),然后再放long long
,都沒關系。
請改用1LL << rot
。
(a)根據C11 6.5.7 Bitwise shift operators
,損壞是指不確定的行為:
對每個操作數執行整數提升。 結果的類型是提升后的左操作數的類型。 如果右操作數的值為負或大於或等於提升的左操作數的寬度,則行為是不確定的。
至於“為什么調試構建會產生不同的輸出(如果我將變量作為參數而不是常量進行移位)”,這是未定義行為的多變之一-實際上,任何可能發生的事情都是允許發生的。 播放derisive_laughter.ogg
並格式化硬盤:-)完全在其權利之內。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.