È un bug in std :: gcd?


14

Mi sono imbattuto in questo comportamento std::gcdche 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::gcddovrebbero 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.


interessante notare che gcc compila 2 in per stampare solo il valore ma un int e un unsigned no: godbolt.org/z/koEVHh
Alan Birtles,

Cosa -120 % 10u? (Suggerimento: non è 0.) Sì, bug.
TC

@TC Sì, il casting -120a unsignedrisulterà in 4294967176quale % 10uè 6. La mia domanda era piuttosto se questo comportamento fosse effettivamente errato, come sembra.
dave,

@AlanBirtles In quel caso, non ci sarà cast unsigned, quindi nessun bug
dave

Risposte:


10

Sembra un bug in libstc ++. Se aggiungi -stdlib=libc++alla riga di comando CE, otterrai:

-120 120
10 10
10
10
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.