Điều thú vị là, nếu chúng ta sử dụng Blob::a
thay vào đó, clang
không phàn nàn:
auto c = Blob::a;
này không nên quan trọng để xác định nếu nó là ODR được sử dụng hay không. Vì vậy, điều này trông giống như một lỗi clang
mà tôi có thể tái sản xuất trên clang 3.7 không chỉ sử dụng tối ưu hóa. Chúng ta có thể nói đây là một vấn đề ODR kể từ khi thêm một ra khỏi định nghĩa lớp sửa chữa các vấn đề (see it live):
constexpr float Blob::a ;
Vì vậy, khi làm bạn cần phải xác định một thành viên lớp constexpr tĩnh? Này được đề cập trong phần 9.4.2
[class.static.data] mà nói (tôi nhấn mạnh đi về phía trước):
A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.
Nó đòi hỏi một định nghĩa nếu nó được ODR-sử dụng. Nó có được sử dụng không? Không có nó không phải là. Bản gốc C++ 11 từ ngữ trong phần 3.2
[basic.def.odr] nói:
An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately applied.
a
đáp ứng cả hai điều kiện, đó là một biểu hiện liên tục và chuyển đổi giá trị trái-to-rvalue ngay lập tức được áp dụng.Defect Report 712 đã thay đổi từ ngữ áp dụng cho C++ 11 vì nó là một báo cáo lỗi và 3.2
nay nói:
A variable x whose name appears as a potentially-evaluated expression ex is odr-used unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression
Kết quả tiềm năng phù hợp sẽ là:
If e is an id-expression (5.1.1), the set contains only e.
nó là một biểu hiện thường xuyên và chuyển đổi lvalue-to-rvalue được áp dụng để nó không được sử dụng odr.
Trình biên dịch nào? – P0W
Phiên bản Ubuntu clang 3.5.0-4ubuntu2 (thẻ/RELEASE_350/final) –
@Deduplicator 'error: thành phần dữ liệu không tĩnh không thể là constexpr; bạn có dự định làm cho nó tĩnh? ' –