Apple Clang и numeric_limits<без знака __int128>:: max () равно 0?
Я пытаюсь найти лучший способ обойти очевидную ошибку, где 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;
}
__SIZEOF_INT128__ >= 16
Тест пришел из обсуждения в списке рассылки GCC в 128-битном целом числе - бессмысленная документация?,
И результат:
$ 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
1 ответ
Написать notstd::numeric_limits<T>:std::numeric_limits<T>
Специализируется, если для T
у которых есть ошибка, перегрузка static max()
(и все остальное) с правильным поведением.
использование notstd::numeric_limits
в Add
,
Или используйте более новый компилятор и / или стандартную библиотеку.