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()) {} };
上面将打印“栏”,然后“富”,即使直观地假设顺序是写在初始化列表中。
或者,如果x
和y
是带有构造函数的某些用户定义的types,则该构造函数也可能具有副作用,具有相同的非显而易见的结果。
当一个成员的初始化器引用另一个成员时,它也可以performance出来。
其他答案提供了一些很好的例子来certificate警告的select。 我想我会提供一些历史背景。 C ++的创build者Bjarne Stroustrup在他的书“C ++编程语言” (第3版,第259页)中解释说:
在包含类自己的构造函数的主体被执行之前调用成员的构造函数。 构造函数按照它们在类中声明的顺序调用,而不是按它们在初始化程序列表中的显示顺序调用。 为了避免混淆,最好按声明顺序指定初始值设定项。 成员析构函数按照与构造相反的顺序调用。
警告存在,因为如果你只是阅读构造函数,它看起来像j
在i
之前得到初始化。 如果用来初始化另一个,就会成为一个问题
struct A { int i; int j; A(): j (0), i (this->j) { } };
当你只是看构造函数,这看起来很安全。 但实际上, j
在初始化j
还没有被初始化,所以代码不能按预期工作。 因此警告。