簡體   English   中英

右移G ++產生意外結果

[英]Unexpected result from shift right g++

我發現將uint64_t值右移64位或更多時,看起來是異常結果。 我曾期望下面的代碼輸出值0,但不會-輸出值>> 2-但僅適用於g ++。

#include <iostream>
#include <cstdint>
using namespace std;
int main(void)
{
    uint64_t value = 0x5d4d629e80d5489UL;
    int shift = 66;
    cout << hex << (value >> shift) << endl;
    return 0;
}

我編譯並運行:

$ g++ -std=c++0x mad.cpp
$ ./a.out
175358a7a035522
$ uname -a
Linux svr 3.2.0-26-generic #41-Ubuntu SMP Thu Jun 14 17:49:24 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ g++ --version 
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

在另一個使用g ++(Debian 4.4.5-8)4.4.5的Linux機器上,我得到了相同的行為。 但是,當我使用Visual Studio C ++(Express Edition)進行編譯時,我沒有得到相同的行為-我得到的是我最初期望的結果-即0。

我想知道,當x和y為序數且y大於x中的位數時,假設C ++中的x >> y應該產生0是否應該是安全的。 這是g ++錯誤-還是Visual C ++在這里不符合要求? 我假設這不是/不應該是未定義的行為嗎? 這可能是特定於CPU的嗎?

我意識到,我總是可以對超過8 * sizeof(value)的每個移位進行顯式檢查-但這會引入一個我希望避免在某些性能關鍵代碼中使用的分支。

這是一個已知問題嗎?如果是這樣,為了一致地進行跨平台評估,推薦的策略是什么?

來自C ++標准的有關移位運算符的信息:

如果右操作數大於或等於提升后的左操作數的位長度,則該行為是不確定的。

此行為是未定義的。
考慮一些有關如何移位太多位以及如何保護自己免受其影響的讀物INT34-C。 不要移位負數個位數或多於操作數中的位數

行為未定義的原因之一是它取決於底層硬件,而底層硬件以不同的方式實現轉換。

在原始的8086上,按要求的次數執行移位,每個位置使用一個時鍾刻度。 很快發現,這導致保證的中斷響應時間非常糟糕

因此,從286開始,硬件將屏蔽移位計數,僅使用低位。 這是當66變為2位置偏移時看到的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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