Mi sono imbattuto in questo comportamento std::gcd
che ho trovato inaspettato:
#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;
}
Esegui su compilatore Explorer
Secondo cppreference entrambe le chiamate a std::gcd
dovrebbero cedere 10
, poiché tutte le condizioni preliminari sono soddisfatte.
In particolare, è richiesto solo che i valori assoluti di entrambi gli operandi siano rappresentabili nel loro tipo comune:
Se uno dei due | m | oppure | n | non è rappresentabile come valore di tipo
std::common_type_t<M, N>
, il comportamento non è definito.
Eppure la prima chiamata ritorna 2
. Mi sto perdendo qualcosa qui? Sia gcc che clang si comportano in questo modo.
-120 % 10u
? (Suggerimento: non è 0.) Sì, bug.
-120
a unsigned
risulterà in 4294967176
quale % 10u
è 6
. La mia domanda era piuttosto se questo comportamento fosse effettivamente errato, come sembra.
unsigned
, quindi nessun bug