2015-05-31 47 views
0

我想檢查一些大的計算內存需求(存儲在unsigned long long)將大致與用於編譯我的代碼的內存模型兼容。將無符號整數右移UB的總位數?

我認爲只要內存需求適合虛擬地址空間(獨立於實際的操作系統限制),將指針中的位數右移需要的位數就會導致0。

不幸的是,在某些編譯器上將64位數字移64位時,我發現了一些意想不到的結果。

小演示:

const int ubits = sizeof (unsigned)*8; // number of bits, assuming 8 per byte 
const int ullbits = sizeof (unsigned long long)*8; 
cout << ubits << " bits for an unsigned\n"; 
cout << ullbits << " bits for a unsigned long long \n"; 

unsigned utest=numeric_limits<unsigned>::max(); // some big numbers 
unsigned long long ulltest=numeric_limits<unsigned long long>::max(); 

cout << "unsigned "<<utest << " rshift by " << ubits << " = " 
    << (utest>>ubits)<<endl; 
cout << "unsigned long long "<<ulltest << " rshift by " << ullbits << " = " 
    << (ulltest>>ullbits)<<endl; 

我預計這兩種顯示rshit結果爲0。

works as expected with gcc

但隨着MSVC 13:

  • 在32位調試:無符號的32位RSHIFT沒有效果(顯示原始數),但長長爲0按預期無符號的64位的移位。
  • 64位調試:在兩種情況下,rshift都沒有影響。
  • 32位和64位版本:在兩種情況下rshif都爲0。

我想知道這是一個編譯器錯誤,或者如果這是未定義的行爲。

+0

我已經標記爲重複。即使另一個問題不完全相同,這些答案也回答了這個問題,提供了規範和基本原理的參考。 – Nemo

回答

5

根據C++標準(5.8移位運算符)

  1. ... 的行爲是不確定如果將右操作數是負的,或者大於或等於比特長度推廣 左操作數

同樣被寫入C標準的(6.5.7按位移OPER ators)

3對每個操作數執行整數提升。結果的 類型是提升的左操作數的類型。如果右操作數的值 爲負或者大於或等於提升的左操作數的寬度 ,則行爲未定義