Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apple Clang and numeric_limits<unsigned __int128>::max() is 0?

I'm trying to figure out the best way to work around an apparent bug where numeric_limits<T>::max() returns 0 rather than the maximum value.

First, the test program:

$ 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;
}

The __SIZEOF_INT128__ >= 16 test came from a discussion on the GCC mailing list at 128-bit integer - nonsensical documentation?.

And the result:

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

Apple has also abandoned the platform and tools, so a bug report won't get the problem fixed.

How can we work around the issue?


I'm not sure how to proceed. To fix the problem in the code, as opposed to the minimal example above, we really need to override the function in the std namespace. But overriding a function in std is not allowed.

Here's an example of why its a problem in the real code:

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;
}

In the code above, we have to provide a full specialization for every combination of T1 = __int128 and T2 imaginable. Its not realistic.


The compiler version on the problematic machine:

$ 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

However, jumping over to a non-Apple test machine produces expected results:

$ 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
like image 402
jww Avatar asked Oct 29 '25 17:10

jww


1 Answers

Write notstd::numeric_limits<T>:std::numeric_limits<T>

Specialize if for T which have a bug, overloading static max() (and whatever else) with the right behaviour.

Use notstd::numeric_limits in Add.

Or use a newer compiler and/or standard library.

like image 191
Yakk - Adam Nevraumont Avatar answered Oct 31 '25 07:10

Yakk - Adam Nevraumont



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!