Ist numeric_limits <int> :: is_modulo logisch widersprüchlich?

Imeine andere Frage, das Thema vonstd::numeric_limits<int>::is_modulo ergab sich. Aber je mehr ich darüber nachdenke, desto mehr scheint etwas mit der Spezifikation oder mit GCC oder beiden nicht zu stimmen.

Lassen Sie mich mit einem Code beginnen:

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

Wenn ich das mit kompiliereg++ -O3 -std=c++11 (x86_64 GCC 4.7.2) erzeugt die folgende Ausgabe:

1 -2147483648 1

Das ist,is_modulo ist wahr, eins plusINT_MAX ist negativ und eins plusINT_MAX ist größer alsINT_MAX.

Wenn Sie der Typ sind, der eine realistische Chance hat, diese Frage zu beantworten, wissen Sie bereits, was hier passiert ist. Die C ++ - Spezifikation besagt, dass der Ganzzahlüberlauf Undefiniertes Verhalten ist. Der Compiler darf davon ausgehen, dass Sie dies nicht tun. daher das Argument zux+1 kann nicht seinINT_MAX; Daher kann (und wird) der Compiler das kompilierentest Funktion, um zurückzukehrentrue bedingungslos. So weit, ist es gut.

DieC ++ 11 spec sagt auch (18.3.2.4 Absätze 60-61):

static constexpr is_modulo;

True, wenn der Typ modulo.222 ist. Ein Typ ist modulo if für jede Operation, die einbezieht+, -, oder* auf Werten dieses Typs, deren Ergebnis außerhalb des Bereichs liegen würde[min(),max()]weicht der zurückgegebene Wert vom wahren Wert um ein ganzzahliges Vielfaches von abmax() - min() + 1.

Bei den meisten Maschinen ist dies der Fallfalse für schwimmende Typen,true für vorzeichenlose ganze Zahlen undtrue für vorzeichenbehaftete ganze Zahlen.

Beachten Sie, dass Abschnitt 5 Absatz (4) weiterhin lautet: "Wenn während der Auswertung eines Ausdrucks das Ergebnis nicht mathematisch definiert ist oder nicht im Bereich der darstellbaren Werte für seinen Typ liegt, ist das Verhalten undefiniert." Es gibt keine Erwähnung vonis_modulo == true eine Ausnahme erstellen.

Daher scheint mir der Standard logisch widersprüchlich zu sein, da ein Ganzzahlüberlauf nicht gleichzeitig definiert und undefiniert werden kann. Zumindest ist GCC nicht konform, weil es dies getan hatis_modulo wietrue Auch wenn die vorzeichenbehaftete Arithmetik mit Sicherheit kein Problem darstellt.

Ist der Standard Buggy? Ist das GCC nicht konform? Vermisse ich etwas?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage