2013-06-21 50 views
6

Tôi vừa cố gắng biên dịch một phần thân mã khá lớn bằng cách sử dụng clang 3.3 với các tệp tiêu đề thư viện chuẩn GCC 4.7.3 trên Ubuntu 13.04. Điều này tất cả đều tốt ngoại trừ một vấn đề. Mã này đã được biên dịch với gói Ubuntu clang 3.2 tiêu chuẩn trên máy này vì vậy tôi giả định đây là một số thay đổi trong trình biên dịch clang 3.3. Vấn đề liên quan đến const và constexpr sử dụng tiêu đề phức tạp. Đặc biệt các loại phức tạp có khối mã sau đâyclang 3.3 và GCC 4.7 const v's constexpr

#ifdef __GXX_EXPERIMENTAL_CXX0X__ 
     // _GLIBCXX_RESOLVE_LIB_DEFECTS 
     // DR 387. std::complex over-encapsulated. 
     constexpr double 
     real() { return __real__ _M_value; } 

     constexpr double 
     imag() { return __imag__ _M_value; } 
#else 
     double& 
     real() { return __real__ _M_value; } 

     const double& 
     real() const { return __real__ _M_value; } 

     double& 
     imag() { return __imag__ _M_value; } 

     const double& 
     imag() const { return __imag__ _M_value; } 
#endif 

Trong biên dịch của tôi, tôi nhập khối đầu tiên của mã và quá trình biên dịch thấy

constexpr double real() { return __real__ _M_value; } 

Điều này dẫn đến kêu vang sản xuất một lỗi mà thực chức năng thành viên không phải là const với sau đây

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/complex:1212:7: 
note: candidate function not viable: 'this' argument has type 'const complex<double>', 
     but method is not marked const 

     real() { return __real__ _M_value; } 

Tôi đã đọc bài viết sau Difference between `constexpr` and `const` và một vài tài liệu tương tự khác nhưng tôi vẫn chưa thực sự rõ ràng nếu đây là một vấn đề tiêu đề GCC hoặc một vấn đề trình biên dịch clang. Cảm giác của tôi là một hàm thành viên được đánh dấu constexpr nên được trình biên dịch xem như là const trong trường hợp clang là sai.

+0

Bạn đang sử dụng cài đặt trình biên dịch nào? –

Trả lời

13

Theo status page cho tiếng kêu, N3652 Relaxing requirements on constexpr functions được triển khai một phần. Bài báo này đã tạo ra một thay đổi lớn. Đoạn sau đã bị xóa.

Trình chỉ định constexpr cho hàm thành viên không tĩnh không phải là hàm tạo tuyên bố hàm thành viên đó là const (9.3.1).

Thay đổi này có nghĩa là chức năng của bạn không thể được gọi trên các đối tượng const nữa. Ngoài ra, hãy xem Fixing constexpr member functions without const là một đề xuất để sửa các khu vực đó của thư viện.

+1

Cảm ơn, bạn đã phát hiện ra. Trang trạng thái cho GCC http://gcc.gnu.org/projects/cxx1y.html cho biết N3652 chưa được triển khai. Tôi cũng phát hiện ra việc xây dựng clang của chúng ta đã có -std = C++ 1y rồi. Sau khi chuyển đổi mà clang tắt không còn tạo ra lỗi. – goneskiing