Me deparei com esse comportamento std::gcd
que achei inesperado:
#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;
}
Executar no explorador de compilador
De acordo com a cppreference, ambas as chamadas std::gcd
devem render 10
, pois todas as pré-condições são atendidas.
Em particular, é necessário apenas que os valores absolutos de ambos os operandos sejam representáveis em seu tipo comum:
Se | m | ou | n | não é representável como um valor do tipo
std::common_type_t<M, N>
, o comportamento é indefinido.
No entanto, a primeira chamada retorna 2
. Estou faltando alguma coisa aqui? Tanto o gcc quanto o clang se comportam dessa maneira.
Curiosamente gcc compila 2 ints para apenas imprimir o valor, mas um int e um sem assinatura não: godbolt.org/z/koEVHh
—
Alan Birtles
O que é
—
TC
-120 % 10u
? (Dica: não é 0.) Sim, bug.
@TC Sim, a transmissão
—
dave
-120
para unsigned
resultará em 4294967176
qual % 10u
é 6
. Minha pergunta foi: se esse comportamento é realmente incorreto, o que parece ser.
@AlanBirtles Nesse caso, não haverá conversão para
—
dave
unsigned
, portanto, também não haverá erros
Reportado como gcc.gnu.org/bugzilla/show_bug.cgi?id=92978
—
TC