g ++ -Wreorder有什么意义?

g ++ -Wall选项包括-Wreorder。 下面介绍这个选项的作用。 我不明白为什么有人会关心(特别是在-Wall中默认打开这个function)。

 -Wreorder(仅限C ++)
  警告代码中给出的成员初始值设定项的顺序不是
  匹配他们必须执行的顺序。 例如:

     struct A {
       int i;
       int j;
       A():j(0),i(1){}
     };

  编译器将重新排列i和j的成员初始值设定项
  匹配成员的声明顺序,发出警告
  影响。 此警告由-Wall启用。

考虑:

struct A { int i; int j; A() : j(0), i(j) { } }; 

现在i被初始化为一个未知的值,而不是零。

或者, i的初始化可能有一些副作用,其中的顺序是重要的。 例如

 A(int n) : j(n++), i(n++) { } 

问题是有人可能会在构造函数中看到成员初始化的列表,并认为它们是按照这个顺序执行的(j先,然后是i)。 他们不是,他们是按照成员在class上定义的顺序执行的。

假设你写了A(): j(0), i(j) {} 。 有人可能会读到,并认为我最终的值为0.它不是,因为你用j初始化它,其中包含垃圾,因为它没有被初始化。

警告提醒你写A(): i(j), j(0) {} ,希望看起来更腥。

这可以咬你,如果你的初始化有副作用。 考虑:

 int foo() { puts("foo"); return 1; } int bar() { puts("bar"); return 2; } struct baz { int x, y; baz() : y(foo()), x(bar()) {} }; 

上面将打印“栏”,然后“富”,即使直观地假设顺序是写在初始化列表中。

或者,如果xy是带有构造函数的某些用户定义的types,则该构造函数也可能具有副作用,具有相同的非显而易见的结果。

当一个成员的初始化器引用另一个成员时,它也可以performance出来。

其他答案提供了一些很好的例子来certificate警告的select。 我想我会提供一些历史背景。 C ++的创build者Bjarne Stroustrup在他的书“C ++编程语言” (第3版,第259页)中解释说:

在包含类自己的构造函数的主体被执行之前调用成员的构造函数。 构造函数按照它们在类中声明的顺序调用,而不是按它们在初始化程序列表中的显示顺序调用。 为了避免混淆,最好按声明顺序指定初始值设定项。 成员析构函数按照与构造相反的顺序调用。

警告存在,因为如果你只是阅读构造函数,它看起来像ji之前得到初始化。 如果用来初始化另一个,就会成为一个问题

 struct A { int i; int j; A(): j (0), i (this->j) { } }; 

当你只是看构造函数,这看起来很安全。 但实际上, j在初始化j还没有被初始化,所以代码不能按预期工作。 因此警告。