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,

Или используйте более новый компилятор и / или стандартную библиотеку.

Другие вопросы по тегам