簡體   English   中英

左移有些意外的行為<

[英]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 << 321LL << rot將為您帶來更多運氣。 這導致使用long long類型對表達式求值。

當前,您的程序的行為是不確定的,因為當您寫入1 << 32時,您正在過度轉換類型。 還要注意, 1 << 32是編譯時可評估的常量表達式,而1 << rot不是。 這可能解釋了使用變量和常量之間觀察到的差異。

如果rotint ,則表達式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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM