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接受上面的代码,但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
只有通过中间基础访问值'i'时才是constexpr。 哪个编译器是正确的?
答案 0 :(得分:-2)
static_cast
是UB,非标准布局类(具有虚拟或非公共成员或基础或多重继承的类)之间的static_cast
也是如此。因此,要使上面的代码定义明确,您需要公共继承
struct base : public root{};
struct derive : public base{};
并且您只能static_cast
从derive
到base
或root
,从base
到root
,而不是在另一个方向。
鉴于GCC通常的语义,它可能“应该”接受你的代码,但它也没有意义,因为它依赖于非标准的行为。