重新排序成员声明

Reordering member declaration

本文关键字:成员 声明 排序 新排序      更新时间:2023-10-16

c++标准中引用了3.3.7/1:

如果对类中的成员声明重新排序会产生另一个有效程序在(1)和(2)下,程序是病态的,没有诊断必需的。

这是什么意思?你能找到一个这样的重新排序声明的例子吗?

考虑这个程序:

double foo;
class Bar {
    std::vector<decltype(foo)> v;
    int foo;
};

重新排序 Bar::vBar::foo如下:

double foo;
class Bar {
    int foo;
    std::vector<decltype(foo)> v;
};

将产生一个在其他方面有效的替代程序,因此该程序违反了引用的规则。

(一个版本的)gcc选择在第一种情况下发出错误,但使用第二种变体("no diagnostic is required")进行编译。

std::vector<decltype(::foo)> v;std::vector<decltype(Bar::foo)> v;是有效的替代(后者只有在首先声明Bar::foo时才有可能)。

这种情况的一个例子是您可以在对象构造中得到的常见错误。代码变体1和2说明了这一点。代码变体1:

class C
{
  C() : a1(0), a2(a1)
  {
  }
  int a1;
  int a2;
};

代码变体2:

class C
{
  C() : a1(0), a2(a1)
  {
  }
  int a2;
  int a1;
};

注意,在变量2 a1和a2中,成员的声明顺序被改变了。好的编译器会对代码变体2提供警告:"成员初始化不符合声明顺序"。问题是,在代码变体2程序行为是未定义的。一些编译器将生成a2将初始化为0的代码(例如,据我猜测Visual Studio编译器),一些将生成a2值未定义的代码,而在代码变体1中,任何编译器都会提供正确的代码。这就是你需要的例子