2017-11-01 22 views
7
struct root 
{ 
    int i = 0; 
}; 

struct base: root{}; 
struct derive: base{}; 

constexpr derive d0; 

int main() 
{ 
    constexpr auto& r = static_cast<root const&>(d0); 
    constexpr auto& b = static_cast<base const&>(r); 
    constexpr auto& d = static_cast<derive const&>(r); 

    static_assert(d0.i == 0, ""); // ok 
    static_assert(r.i == 0, ""); // ok 
    static_assert(b.i == 0, ""); // error in gcc 
    static_assert(d.i == 0, ""); // ok 
} 

Clang chấp nhận các mã trên nhưng 7.2.0 gcc biên dịch với lỗi dưới đây:Có phải constexpr đang truy cập thành viên cấp cơ sở từ tham chiếu lớp dẫn xuất trung gian không?

prog.cc:17:5: error: non-constant condition for static assertion 
    static_assert(b.i == 0, ""); 
    ^~~~~~~~~~~~~ 
prog.cc:17:5: error: accessing value of 'd.derive::<anonymous>.base::<anonymous>' through a 'const base' 
glvalue in a constant 

Nó không phải là constexpr chỉ khi tôi truy cập giá trị 'i' qua cơ sở trung gian. Trình biên dịch nào là chính xác?

+0

Bạn đang biên soạn đặc tả C++ nào? C++ 17? – dlasalle

+0

được biên dịch với cả C++ 14 và C++ 17 cũng có cùng kết quả. – kwanti

+0

Trường hợp sử dụng thú vị. Tôi chỉ muốn kêu vang trong đó tôi nghĩ rằng nó có lẽ nên được cho phép bởi gcc, nhưng có lẽ họ không cho phép nó bởi vì nó không được đảm bảo an toàn. (chỉ 'dynamic_cast' cho downcasting là) – AndyG

Trả lời

-2

static_cast từ lớp cơ sở đến lớp dẫn xuất là UB, là static_cast giữa các lớp không bố cục tiêu chuẩn (những lớp có thành viên hoặc cơ sở ảo hoặc không công khai hoặc nhiều kế thừa). Vì vậy, để làm cho đoạn code trên được xác định rõ bạn cần thừa kế công

struct base : public root{}; 
struct derive : public base{}; 

và bạn chỉ có thể static_cast từ derive để base hoặc root, và base-root, và không theo một hướng khác.

Với ngữ nghĩa thông thường của GCC, có lẽ "nên" chấp nhận mã của bạn, nhưng cũng có nghĩa là không, vì nó dựa trên hành vi không chuẩn.

+0

Các đường dẫn kế thừa công khai theo mặc định, do đó, đó không phải là vấn đề. – bstamour

+0

'static_cast' từ cơ sở đến nguồn gốc được xác định rõ ràng, cũng như' static_cast' giữa các lớp không bố cục tiêu chuẩn. – Oktalist

Các vấn đề liên quan