"GCC警告" '将在之后初始化'

280

我从无法修改的第三方代码中得到很多这样的警告。 有没有一种方法可以禁用此警告,或者至少在某些区域(如VC++中的#pragma push/pop)禁用它?

示例:

list.h:1122: warning: `list<LogOutput*, allocator<LogOutput*> >::node_alloc_' will be initialized after 
list.h:1117: warning:   `allocator<LogOutput*> list<LogOutput*, allocator<LogOutput*> >::alloc_'

请问您能否贴出几行实际的警告信息?并且告知这是C还是C++,如果您有源代码的话,警告是来自链接器还是编译过程? - csl
7个回答

486

请确保在初始化列表中以与它们在类中出现的顺序相同的顺序出现成员。

Class C {
   int a;
   int b;
   C():b(1),a(2){} //warning, should be C():a(2),b(1)
}

或者你可以使用-Wno-reorder命令


125
这为什么很重要?为什么会有这个警告存在? - Eloff
53
在某些情况下(不建议这样做),变量ba的初始化可能会相互依赖。一个缺乏经验的用户可能会尝试改变初始化顺序以达到某种效果,而警告则清楚地说明这样做是行不通的。 - Gorpik
28
因此,即使声明之间没有关系,声明的顺序也具有语义意义?这多么无意义! - Cuadue
17
这并没有解释为什么会有这个警告,并且引用了“-Wno-reorder”,但没有提到可能导致什么问题。我知道原帖没有要求其他细节,但是对于这样一个高票答案,我至少希望它能提到周围的上下文和注意事项。我们难道不应该回答原帖作者应该写的问题吗? - underscore_d
8
@cp.engr成员的初始化顺序是按照它们声明的顺序进行的,而不是按照初始化列表中的顺序进行的。因此,如果一个成员的初始化依赖于另一个成员,但是声明被交换了,导致被依赖的成员在其依赖项之后被初始化,那么很快就会出现非常糟糕的情况,因为这是纯粹的未定义行为。 - underscore_d
显示剩余3条评论

31
您可以使用-Wno-reorder禁用它。

18

如果您在使用QT时遇到此错误,请将以下内容添加到.pro文件中

QMAKE_CXXFLAGS_WARN_ON += -Wno-reorder

8
Class C {
   int a;
   int b;
   C():b(1),a(2){} //warning, should be C():a(2),b(1)
}

顺序很重要,如果a在b之前初始化,并且a依赖于b,则会出现未定义的行为。


7

使用-Wno-reorder选项(请参考gcc手册)。


7
哇,你找到了一种新的说法来表达RT_M:MIYF(人类是你的朋友) 如果您不介意,我会使用它 :) - Oren S

5
如果您在使用GCC时从库头文件中看到错误,则可以通过使用-isystem代替-I包含头文件来禁用警告。 Clang也有类似的功能。
如果您正在使用CMake,可以为include_directories指定SYSTEM

你能解释一下如何“指定SYSTEM”吗? - einpoklum
1
只需在 include_directories 行末添加字符串 SYSTEM 即可。 - Drew Noakes

1

初始化的顺序并不重要。所有字段都按照它们在类/结构体中定义的顺序进行初始化。但是,如果初始化列表中的顺序不同,gcc/g++将生成警告。只需更改初始化顺序即可避免此警告。但是,您不能在其构造之前使用初始化中定义的字段。这将导致运行时错误。因此,您需要更改定义的顺序。请小心并保持注意力!


OP 想知道如何禁用警告,而不是了解它的含义或修复代码。事实上,帖子中说该代码是第三方的,无法修改。他们不能更改定义的顺序,可能也不能更改初始化的顺序。 - Tim Seguine
3
如果初始化列表中第二个对象是从第一个对象初始化的,但它们在头文件中声明的顺序有误,那么这非常重要。在这种情况下,情况可能会变得非常奇怪。 - underscore_d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接