Я натрапив на таку поведінку, 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;
}
Запустити на компілятор Explorer
Відповідно до cppreference, обидва заклики до цього std::gcd
повинні мати результат 10
, оскільки всі передумови виконуються.
Зокрема, потрібно лише, щоб абсолютні значення обох операндів були представлені в їх загальному типі:
Якщо або | м | або | n | не є репрезентабельним як значення типу
std::common_type_t<M, N>
, поведінка не визначена.
І все ж перший дзвінок повертається 2
. Я щось тут пропускаю? І gcc, і clang так поводяться.
Цікаво, що gcc збирає 2 int, щоб просто надрукувати значення, але int і не підписане: godbolt.org/z/koEVHh
—
Alan
Що
—
ТК
-120 % 10u
? (Підказка: це не 0.) Так, помилка.
@TC Так, кастинг
—
Дейв
-120
для unsigned
цього призведе до того, 4294967176
що % 10u
є 6
. Моє запитання було скоріше, чи така поведінка справді неправильна, що, здається, є.
@AlanBirtles У такому випадку тер не буде відзначений
—
Дейв
unsigned
, тому жодна помилка не буде
Повідомлено як gcc.gnu.org/bugzilla/show_bug.cgi?id=92978
—
ТК