Является ли numeric_limits <int> :: is_modulo логически противоречивым?

ВДругой вопростемаstd::numeric_limits<int>::is_modulo подошел. Но чем больше я думаю об этом, тем больше кажется, что что-то не так со спецификацией, с GCC или с обоими.

Позвольте мне начать с некоторого кода:

#include <limits>
#include <iostream>

bool test(int x)
{
    return x+1 > x;
}

int main(int argc, char *argv[])
{
    int big = std::numeric_limits<int>::max();

    std::cout << std::numeric_limits<int>::is_modulo << " ";
    std::cout << big+1 << " ";
    std::cout << test(big) << "\n";
}

Когда я собираю это сg++ -O3 -std=c++11 (x86_64 GCC 4.7.2), он производит следующий вывод:

1 -2147483648 1

Это,is_modulo верно, один плюсINT_MAX отрицательно, и один плюсINT_MAX больше, чемINT_MAX.

Если вы из тех людей, у которых есть реальная возможность ответить на этот вопрос, вы уже знаете, что здесь произошло. Спецификация C ++ говорит, что целочисленное переполнение - Неопределенное Поведение; компилятор может предположить, что вы этого не делаете; поэтому аргументx+1 не может бытьINT_MAX; поэтому компилятор может (и будет) компилироватьtest функция для возвратаtrue безусловно. Все идет нормально.

ОднакоC ++ 11 spec также говорится (18.3.2.4 параграфы 60-61):

static constexpr is_modulo;

Истинно, если тип является модулем. 222 Тип является модулем, если для любой операции, включающей+, -, или же* на значениях этого типа, результат которых выходит за пределы диапазона[min(),max()]возвращаемое значение отличается от истинного значения на целое число, кратноеmax() - min() + 1.

На большинстве машин этоfalse для плавающих типов,true для целых чисел без знака иtrue для целых чисел со знаком.

Обратите внимание, что параграф (4) раздела 5 по-прежнему гласит: «Если во время вычисления выражения результат не определен математически или не находится в диапазоне представимых значений для его типа, поведение не определено». Там нет упоминания оis_modulo == true создавая исключение

Поэтому мне кажется, что стандарт логически противоречив, потому что целочисленное переполнение не может быть одновременно определено и не определено. Или, по крайней мере, GCC не соответствует, потому что он имеетis_modulo какtrue хотя подписанная арифметика наверняка не оборачивается.

Стандартный глючит? GCC не соответствует? Я что-то пропустил?

Ответы на вопрос(1)

Ваш ответ на вопрос