2

私が編集しているコードでは、以前のプログラマーがシフト演算子を使用して、適度に大きな数を size_t 整数に追加していました。デバッグ目的でこの特定の整数を試してみたところ、数値を変更しても予測可能な結果が得られないことがわかりました。

入力:

std::size_t
    foo1 = 100000 << 20,
    foo2 = 200000 << 20,
    foo3 = 300000 << 20,
    foo4 = 400000 << 20;
std::cout << "foos1-4:";
std::cout << foo1;
std::cout << foo2;
std::cout << foo3;
std::cout << foo4;

収量:

foos1-4:
1778384896
18446744072971354112
1040187392
18446744072233156608

私はそれがある種のオーバーフローエラーであることを知っていますが、(私の限られた知識では) size_t はそれらを持つべきではありません。私が理解していることから、 size_t は実質的に無制限の数の整数を保持できる符号なし整数型です。

ビットシフト演算子について私が理解していることから、このコードは数値に 2^20 (1048576) を掛ける必要があります。このサイトの他のページへのリンク: ビットごとのシフト (ビットシフト) 演算子とは何ですか? また、どのように機能しますか?

注 - foo1 は 32 桁の 2 進数が切り捨てられたオーバーフロー エラーのように見えますが、他のすべては完全にランダムに見えます。

http://en.cppreference.com/w/cpp/types/size_tから: std::size_t は、任意の型 (配列を含む) の理論的に可能なオブジェクトの最大サイズを格納できます。そのことから、問題は整数の宣言方法またはビットシフトの動作方法にあるに違いないと思います。

どうしたの?

4

1 に答える 1

11

問題は使用されstd::size_tているintリテラルではありません。UL次のように接尾辞を使用して、それらを十分に長くすることができます。

#include <iostream>

int main()
{
std::size_t
    foo1 = 100000UL << 20,
    foo2 = 200000UL << 20,
    foo3 = 300000UL << 20,
    foo4 = 400000UL << 20;
std::cout << "foos1-4:" << std::endl;
std::cout << foo1 << std::endl;
std::cout << foo2 << std::endl;
std::cout << foo3 << std::endl;
std::cout << foo4 << std::endl;
}

出力:

foos1-4:
104857600000
209715200000
314572800000
419430400000

ライブデモ


また、コンパイラはそれについて正確に警告することに注意してください。

main.cpp:6:19: warning: result of '(100000 << 20)' requires 38 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=]
     foo1 = 100000 << 20,
            ~~~~~~~^~~~~
main.cpp:7:19: warning: result of '(200000 << 20)' requires 39 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=]
     foo2 = 200000 << 20,
            ~~~~~~~^~~~~
main.cpp:8:19: warning: result of '(300000 << 20)' requires 40 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=]
     foo3 = 300000 << 20,
            ~~~~~~~^~~~~
main.cpp:9:19: warning: result of '(400000 << 20)' requires 40 bits to represent, but 'int' only has 32 bits [-Wshift-overflow=]
     foo4 = 400000 << 20;
            ~~~~~~~^~~~~
于 2016-09-15T22:48:59.430 に答える