3

numeric_limits<T>::max()最大値ではなく 0を返す明らかなバグを回避する最善の方法を見つけようとしています。

まず、テスト プログラム:

$ cat test.cxx
#include <iostream>
#include <limits>

int main(int argc, char* argv[])
{
#if (__SIZEOF_INT128__ >= 16)
    std::cout << "__int128 is available" << std::endl;
#else
    std::cout << "__int128 is not available" << std::endl;
#endif

    unsigned __int128 m = std::numeric_limits<unsigned __int128>::max();
    if (m == 0)
        std::cout << "numeric_limits<unsigned __int128>::max() is 0" << std::endl;
    else
        std::cout << "numeric_limits<unsigned __int128>::max() is not 0" << std::endl;

    return 0;
}

このテストは、 128 ビット整数__SIZEOF_INT128__ >= 16での GCC メーリング リストでの議論から生まれました- 無意味なドキュメント? .

そして結果:

$ c++ -Wall test.cxx -o test.exe
$ ./test.exe
__int128 is available
numeric_limits<unsigned __int128>::max() is 0

Apple もプラットフォームとツールを放棄したため、バグ レポートでは問題が修正されません。

この問題を回避するにはどうすればよいですか?


どうすればよいかわかりません。コードの問題を修正するには、上記の最小限の例とは対照的に、名前空間で関数をオーバーライドする必要があります。stdただし、関数のオーバーライドは許可されstdていません

実際のコードで問題になる理由の例を次に示します。

template<class T1, class T2>
T1 Add(const T1& t1, const T2& t2)
{
    if (std::numeric_limits<T1>::max() - t2 > t1)
        throw std::runtime_error("overflow");

    return t1 + t2;
}

上記のコードでは、考えられるすべての と の組み合わせに対して完全な特殊化を提供する必要がT1 = __int128ありT2ます。現実的ではありません。


問題のあるマシンのコンパイラのバージョン:

$ c++ --version
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

ただし、Apple 以外のテスト マシンにジャンプすると、期待どおりの結果が得られます。

$ clang++-3.5 --version
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix

$ clang++-3.5 -Wall test.cxx -o test.exe

$ ./test.exe
__int128 is available
numeric_limits<unsigned __int128>::max() is not 0
4

1 に答える 1