Is this a bug in std::gcd?
Asked Answered
G

1

17

I've come across this behavior of std::gcd that I found unexpected:

#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;
}

Run on compiler explorer

According to cppreference both calls to std::gcd should yield 10, as all preconditions are satisfied.

In particular, it is only required that the absolute values of both operands are representable in their common type:

If either |m| or |n| is not representable as a value of type std::common_type_t<M, N>, the behavior is undefined.

Yet the first call returns 2. Am I missing something here? Both gcc and clang behave this way.

Gosh answered 17/12, 2019 at 17:57 Comment(5)
interestingly gcc compiles 2 ints to just print the value but an int and an unsigned doesn't: godbolt.org/z/koEVHhHelvellyn
What's -120 % 10u? (Hint: it's not 0.) Yes, bug.Mandle
@Mandle Yes, casting -120 to unsigned will result in 4294967176 which % 10u is 6. My question was rather if this behavior is indeed incorrect, which it seems to be.Gosh
@AlanBirtles In that case, ther will be no cast to unsigned, so no bug eitherGosh
Reported as gcc.gnu.org/bugzilla/show_bug.cgi?id=92978Mandle
L
12

Looks like a bug in libstc++. If you add -stdlib=libc++ to the CE command line, you'll get:

-120 120
10 10
10
10
Ladonnalady answered 17/12, 2019 at 18:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.