Ist das ein Fehler in std :: gcd?

14

Ich bin auf dieses Verhalten gestoßen std::gcd, das ich unerwartet fand:

#include <iostream>
#include <numeric>

int main()
{
    int      a = -120;
    unsigned b =  10;

    //both a and b are representable in type C
    using C = std::common_type<decltype(a), decltype(b)>::type;
    C ca = std::abs(a);
    C cb = b;
    std::cout << a << ' ' << ca << '\n';
    std::cout << b << ' ' << cb << '\n';

    //first one should equal second one, but doesn't
    std::cout << std::gcd(a, b) << std::endl;
    std::cout << std::gcd(std::abs(a), b) << std::endl;
}

Führen Sie den Compiler-Explorer aus

Laut cppreference sollten beide Aufrufe std::gcdnachgeben 10, da alle Voraussetzungen erfüllt sind.

Insbesondere ist es nur erforderlich, dass die Absolutwerte beider Operanden in ihrem gemeinsamen Typ darstellbar sind:

Wenn entweder | m | oder | n | ist nicht als Wert vom Typ darstellbar std::common_type_t<M, N>, das Verhalten ist undefiniert.

Der erste Anruf kehrt jedoch zurück 2. Vermisse ich hier etwas? Sowohl gcc als auch clang verhalten sich so.

Dave
quelle
Interessanterweise kompiliert gcc 2 Ints, um nur den Wert zu drucken, ein Int und ein unsigned jedoch nicht: godbolt.org/z/koEVHh
Alan Birtles
Was ist -120 % 10u? (Hinweis: Es ist nicht 0.) Ja, Fehler.
TC
@TC Ja, Casting -120zu unsignedführt zu dem, 4294967176was % 10uist 6. Meine Frage war eher, ob dieses Verhalten tatsächlich falsch ist, was es zu sein scheint.
Dave
@ AlanBirtles In diesem Fall wird es keine Besetzung geben unsigned, also auch kein Fehler
Dave

Antworten:

10

Sieht aus wie ein Fehler in libstc ++. Wenn Sie -stdlib=libc++der CE-Befehlszeile hinzufügen , erhalten Sie:

-120 120
10 10
10
10
Marshall Clow
quelle