2013-03-15 32 views
7

Xét đoạn mã sau (LWS):g ++ vs intel/clang đối số thông qua thứ tự?

#include <iostream> 
#include <chrono> 

inline void test(
    const std::chrono::high_resolution_clock::time_point& first, 
    const std::chrono::high_resolution_clock::time_point& second) 
{ 
    std::cout << first.time_since_epoch().count() << std::endl; 
    std::cout << second.time_since_epoch().count() << std::endl; 
} 

int main(int argc, char* argv[]) 
{ 
    test(std::chrono::high_resolution_clock::now(), 
     std::chrono::high_resolution_clock::now()); 
    return 0; 
} 

Bạn phải chạy nó nhiều lần bởi vì đôi khi, không có khác biệt rõ ràng. Nhưng khi có sự khác biệt rõ ràng giữa thời điểm đánh giá của firstsecond, kết quả là sau dưới g ++:

1363376239363175 
1363376239363174 

và sau đây dưới intel và kêu vang:

1363376267971435 
1363376267971436 

Nó có nghĩa là dưới g ++, đối số second được đánh giá đầu tiên, và bên dưới intel và clang đối số first được đánh giá trước tiên.

Điều nào là đúng theo tiêu chuẩn C++ 11?

+2

Cách gọn gàng để tìm thứ tự đánh giá. – GManNickG

Trả lời

14

Điều nào đúng theo tiêu chuẩn C++ 11?

Cả hai đều được phép. Để trích dẫn tiêu chuẩn (§8.3.6):

Thứ tự đánh giá đối số chức năng không được xác định.

+0

Yup. Điều này đã cắn tôi một vài lần trong sự nghiệp của tôi, trên thực tế. Sự mơ hồ của việc đánh giá các đối số hàm có thể dẫn đến các vấn đề phức tạp. (Tôi nhớ một lần mà lỗi này tồn tại trong nhiều năm, và tôi không thể tìm ra nguyên nhân gốc rễ, và cách giải quyết duy nhất tôi có thể tìm thấy là TẮT TÙY CHỌN TẮT CHO CPP đó.) – StilesCrisis

+0

Ngoài ra, thứ tự có thể phụ thuộc vào việc tối ưu hóa cờ được sử dụng và phần còn lại của mã. –

+0

@StilesCrisis Vâng, và ngay cả khi bạn nhận thức được thứ tự đánh giá đối số không xác định, bạn phải ghi nhớ rằng đối tượng mà phương thức được gọi cũng chỉ là một đối số khác. Đã xảy ra với tôi một lần bởi vì tôi nghĩ * "tốt, để gọi một phương thức thông qua' -> ', trước tiên nó phải đánh giá phía bên trái trước khi bắt đầu xem xét các đối số phương thức, phải không?" *. –

0

Tôi có ví dụ đơn giản hơn một chút để minh họa cùng một vấn đề.

bash$ cat test.cpp 
#include <iostream> 
using namespace std; 
int x = 0; 
int foo() 
{ 
    cout << "foo" << endl; 
    return x++; 
} 
int bar() 
{ 
    cout << "bar" << endl; 
    return x++; 
} 
void test_it(int a, int b) 
{ 
    cout << "a = " << a << endl 
     << "b = " << b << endl; 

} 
int main(int argc, const char *argv[]) 
{ 
    test_it(foo(),bar()); 
    return 0; 
} 

bash$ clang++ test.cpp && ./a.out 
foo 
bar 
a = 0 
b = 1 
bash$ g++ test.cpp && ./a.out 
bar 
foo 
a = 1 
b = 0 
Các vấn đề liên quan