Est-ce un bogue dans std :: gcd?

14

Je suis tombé sur ce comportement std::gcdque j'ai trouvé inattendu:

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

Exécuter sur l'explorateur de compilateur

Selon cppreference, les deux appels à std::gcddevraient céder 10, car toutes les conditions préalables sont remplies.

En particulier, il est seulement nécessaire que les valeurs absolues des deux opérandes soient représentables dans leur type commun:

Si | m | ou | n | n'est pas représentable comme une valeur de type std::common_type_t<M, N>, le comportement n'est pas défini.

Pourtant, le premier appel revient 2. Est-ce que j'ai râté quelque chose? Gcc et clang se comportent de cette façon.

Dave
la source
intéressant, gcc compile 2 ints pour imprimer simplement la valeur, mais pas un int ni un unsigned: godbolt.org/z/koEVHh
Alan Birtles
Quoi -120 % 10u? (Indice: ce n'est pas 0.) Oui, bug.
TC
@TC Oui, la diffusion -120vers unsignedaboutira à 4294967176ce qui % 10uest 6. Ma question était plutôt de savoir si ce comportement est effectivement incorrect, ce qui semble être le cas.
dave
@AlanBirtles Dans ce cas, il n'y aura pas de casting unsigned, donc pas de bug non plus
dave

Réponses:

10

Ressemble à un bogue dans libstc ++. Si vous ajoutez -stdlib=libc++à la ligne de commande CE, vous obtiendrez:

-120 120
10 10
10
10
Marshall Clow
la source