Это ошибка в std :: gcd?

14

Я сталкивался с таким поведением, std::gcdкоторое я нашел неожиданным:

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

Запустить на проводнике компилятора

Согласно cppreference оба вызова std::gcdдолжны дать 10, поскольку все предварительные условия выполнены.

В частности, требуется только, чтобы абсолютные значения обоих операндов были представлены в их общем типе:

Если либо | m | или | n | не представляется как значение типа std::common_type_t<M, N>, поведение не определено.

И все же первый звонок возвращается 2. Я что-то здесь упускаю? И gcc, и clang ведут себя таким образом.

Дейв
источник
интересно, что gcc компилирует 2 целых числа, чтобы просто напечатать значение, а целое число, а неподписанное - нет: godbolt.org/z/koEVHh
Алан
Что -120 % 10u? (Подсказка: это не 0.) Да, ошибка.
TC
@TC Да, приведение -120к unsignedприведет к тому, 4294967176что % 10uесть 6. Мой вопрос был скорее, если это поведение действительно неверно, что кажется.
Дэйва
@AlanBirtles В этом случае Ther не будет приведения к unsigned, так не ошибки либо
Дэйв

Ответы:

10

Похоже, ошибка в libstc ++. Если вы добавите -stdlib=libc++в командную строку CE, вы получите:

-120 120
10 10
10
10
Маршалл Клоу
источник