Isso é um bug no std :: gcd?


14

Me deparei com esse comportamento std::gcdque 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::gcddevem 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 é -120 % 10u? (Dica: não é 0.) Sim, bug.
TC

@TC Sim, a transmissão -120para unsignedresultará em 4294967176qual % 10ué 6. Minha pergunta foi: se esse comportamento é realmente incorreto, o que parece ser.
dave

@AlanBirtles Nesse caso, não haverá conversão para unsigned, portanto, também não haverá erros
dave

Respostas:


10

Parece um bug no libstc ++. Se você adicionar -stdlib=libc++à linha de comando do CE, receberá:

-120 120
10 10
10
10
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.