Czy limity liczbowe <int> :: is_modulo są logicznie sprzeczne?

Winne pytanie, tematstd::numeric_limits<int>::is_modulo podszedł. Ale im więcej o tym myślę, tym bardziej wydaje się, że coś jest nie tak ze specyfikacją lub GCC lub obydwoma.

Zacznę od kodu:

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

Kiedy to kompilujęg++ -O3 -std=c++11 (x86_64 GCC 4.7.2), generuje następujące dane wyjściowe:

1 -2147483648 1

To jest,is_modulo to prawda, jeden plusINT_MAX jest ujemny i jeden plusINT_MAX jest większy niżINT_MAX.

Jeśli jesteś osobą, która ma realistyczną szansę na odpowiedź na to pytanie, już wiesz, co się tutaj stało. Specyfikacja C ++ mówi, że przekroczenie liczby całkowitej to Niezdefiniowane zachowanie; kompilator może założyć, że tego nie robisz; dlatego argument dox+1 nie może byćINT_MAX; dlatego kompilator może (i będzie) skompilowałtest funkcja do powrotutrue bezwarunkowo. Jak na razie dobrze.

JednakżeSpecyfikacja C ++ 11 również mówi (18.3.2.4 paragrafy 60-61):

static constexpr is_modulo;

Prawda, jeśli typ to modulo.222 Typ jest modulo if, dla dowolnej operacji z udziałem+, -lub* na wartościach tego typu, których wynik nie mieści się w zakresie[min(),max()], zwracana wartość różni się od wartości prawdziwej o wielokrotność liczby całkowitejmax() - min() + 1.

Na większości maszyn takfalse dla typów pływającychtrue dla liczb całkowitych bez znaku itrue dla liczb całkowitych podpisanych.

Zwróć uwagę, że sekcja 5 akapit (4) wciąż brzmi: „Jeśli podczas oceny wyrażenia wynik nie jest matematycznie zdefiniowany lub nie mieści się w zakresie wartości reprezentowalnych dla jego typu, zachowanie jest niezdefiniowane”. Nie ma wzmianki ois_modulo == true tworzenie wyjątku.

Wygląda więc na to, że standard jest logicznie sprzeczny, ponieważ przekroczenie liczby całkowitej nie może być jednocześnie zdefiniowane i niezdefiniowane. A przynajmniej GCC jest niezgodne, ponieważ mais_modulo tak jaktrue mimo że podpisana arytmetyka z pewnością nie zawija się.

Czy standardowy buggy? Czy GCC jest niezgodny? Czy czegoś mi brakuje?

questionAnswers(1)

yourAnswerToTheQuestion