Đây có phải là một lỗi trong std :: gcd?


14

Tôi đã bắt gặp hành vi này std::gcdmà 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::gcdnê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ì -120 % 10u? (Gợi ý: không phải 0.) Có, lỗi.
TC

@TC Vâng, đúc -120để unsignedsẽ dẫn đến 4294967176đó % 10u6. 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à.
dave

@AlanBirtles Trong trường hợp đó, sẽ không có diễn viên nào unsigned, vì vậy cũng không có lỗi
dave

Câu trả lời:


10

Trông giống như một lỗi trong libstc ++. Nếu bạn thêm -stdlib=libc++vào dòng lệnh CE, bạn sẽ nhận được:

-120 120
10 10
10
10
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.