问题
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
回答1:
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.
来源:https://stackoverflow.com/questions/41666815/apple-clang-and-numeric-limitsunsigned-int128max-is-0