Tôi đã bắt gặp hành vi này std::gcd
mà tôi thấy bất ngờ:
#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;
}
Chạy trên trình biên dịch explorer
Theo cppreference cả hai cuộc gọi std::gcd
nên mang lại 10
, vì tất cả các điều kiện tiên quyết được thỏa mãn.
Cụ thể, chỉ yêu cầu các giá trị tuyệt đối của cả hai toán hạng đều có thể biểu diễn theo kiểu chung:
Nếu một trong hai | m | hoặc | n | không thể biểu diễn dưới dạng giá trị của loại
std::common_type_t<M, N>
, hành vi không được xác định.
Tuy nhiên, cuộc gọi đầu tiên trở lại 2
. Am i thiếu cái gì ở đây? Cả gcc và clang đều hành xử theo cách này.
thú vị gcc biên dịch 2 int để chỉ in giá trị nhưng một int và không dấu không: godbolt.org/z/koEVHh
—
Alan Birtles
Có gì
—
TC
-120 % 10u
? (Gợi ý: không phải 0.) Có, lỗi.
@TC Vâng, đúc
—
dave
-120
để unsigned
sẽ dẫn đến 4294967176
đó % 10u
là 6
. Câu hỏi của tôi là thay vì hành vi này thực sự không chính xác, mà nó dường như là.
@AlanBirtles Trong trường hợp đó, sẽ không có diễn viên nào
—
dave
unsigned
, vì vậy cũng không có lỗi
Được báo cáo là gcc.gnu.org/ormszilla/show_orms.cgi?id=92978
—
TC