在特定变量上禁用GCC"可以使用未初始化"

edA*_*a-y 30 c++ gcc compiler-warnings

我在堆栈变量上收到此警告:

warning: object.member may be used uninitialized in this function
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我不希望强制初始化只是为了消除警告,因为它消耗CPU周期.变量是POD结构,所以memset它不是零成本.我可以验证变量从未使用过未初始化,所以我只想禁止它的警告.

一般来说,我确实需要警告,而不是在这个特定情况下的特定变量.我怎么能抑制警告?


看起来pragma诊断是正确的方法,但它们需要相当新版本的GCC(4.6)

在该版本之前,没有可接受的解决方案.

Naw*_*waz 33

试着这样做:

 #pragma GCC diagnostic ignored "-Wuninitialized"
        foo(b);         /* no diagnostic for this one */
Run Code Online (Sandbox Code Playgroud)

该编译有三种有趣和有益的口味:warning,error,ignored.有关其用法,请参见6.56.10诊断编排.链接说,

GCC允许用户有选择地启用或禁用某些类型的诊断,并更改诊断的类型.例如,项目的策略可能要求所有源使用-Werror进行编译,但某些文件可能具有允许特定类型警告的异常.或者,项目可以选择性地启用诊断并根据定义的预处理器宏将其视为错误.

  • 这是我第一次遇到它.它可能需要几年才能在野外被人看到.多么有用的答案:) (3认同)
  • 这不允许在函数内使用(所以说GCC). (2认同)
  • 其实这*不是*我想要的。这将禁用整个文件的警告,而不仅仅是特定功能。 (2认同)
  • @ edA-qa mort-ora-y:我想.它得到[GCC 4.6.0]的支持(http://gcc.gnu.org/gcc-4.6/changes.html) (2认同)

Map*_*paM 10

接受的答案有两个大问题,需要的不仅仅是评论。首先,它停用整个文件的警告。如果该编译指示位于标题中,则可能更多。警告很有用,如果它确实是误报,则应该为尽可能小的一堆代码禁用警告。

然后 OP 中的警告是“可能未初始化”,它被 -Wmaybe-uninitialized 停用,而不是 -Wuninitialized。

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
function() or int variable;
#pragma GCC diagnostic pop
Run Code Online (Sandbox Code Playgroud)


Mar*_*k B 6

@Nawaz已经按照具体要求回答了这个问题,但你是否认为你需要这个问题可能表明你struct过早/在一个较少嵌套的范围内宣布你的问题?通常情况下,如果您可以struct在实际初始化它的位置声明您的位置,而不是提前声明它并在不同位置填充它.

此外,即使您可以验证它现在从未使用过未初始化,如果其他人在将来添加新的代码路径并且未正确初始化该怎么办?如果你禁用警告,那么它将默默编译并可能以意想不到的方式中断.除非您能够证明初始化正在占用程序CPU的可测量量,否则最好先预先进行初始化.

  • @ edA-qa mort-ora-y如果没有办法有效地默认构造其中一个对象,那么听起来更像是你不应该创建一个未初始化的对象.在知道如何创建对象之前,您是否能够延迟构建? (4认同)
  • +1始终编码,好像下一个触摸代码的人比你自己笨.甚至可能是你从现在开始的一年,当你不记得你需要担心这个值被初始化时.也许如果他发布他的代码,我们可以帮助他找到一种相对有效的方法来删除警告. (2认同)
  • 我不会对此投票;)但是我强烈不同意当你不知道将它初始化为什么时,应该初始化某些东西的情绪,只是为了初始化.此时您可能会将其初始化为任何内容(无论如何都会被覆盖),之后如果有人添加实际开始使用此代码的代码 - 您真的会更好吗?你应该只是在第一次使用变量的前面压制警告.使用`#pragma GCC diagnostics push/pop`来避免在其他地方发出警告. (2认同)

Fle*_*exo 5

GCC 区分未初始化和自初始化,例如编译:

int main() {
   int i = i;
   return i;
}
Run Code Online (Sandbox Code Playgroud)

随着gcc -Wall -Wextra没有给出警告,除非你明确添加-Winit-self为好,但它得到由我的快速测试完全优化掉了。