Je suis tombé sur ce comportement std::gcd
que 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::gcd
devraient 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.
-120 % 10u
? (Indice: ce n'est pas 0.) Oui, bug.
-120
vers unsigned
aboutira à 4294967176
ce qui % 10u
est 6
. Ma question était plutôt de savoir si ce comportement est effectivement incorrect, ce qui semble être le cas.
unsigned
, donc pas de bug non plus