是constexpr从中间派生类引用访问基类成员吗?

kwa*_*nti 7 c++ constexpr

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
}
Run Code Online (Sandbox Code Playgroud)

Clang接受上面的代码,但是gcc 7.2.0编译错误如下:

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
Run Code Online (Sandbox Code Playgroud)

只有当我通过中间基础访问值'i'时,它才是constexpr.哪个编译器正确?

Ray*_*mel -2

static_cast从基类到派生类是 UB,static_cast非标准布局类(具有虚拟或非公共成员或基类或多重继承的类)之间也是如此。因此,为了使上述代码定义良好,您需要公共继承

struct base : public root{};
struct derive : public base{};
Run Code Online (Sandbox Code Playgroud)

您只能static_castderivebaseroot,以及从baseroot,而不能从另一个方向。

考虑到 GCC 的通常语义,它可能“应该”接受您的代码,但它不接受也是有道理的,因为它依赖于非标准行为。