如何优雅地克服毫无意义的C++编译器警告?

问题描述 投票:0回答:7

这个问题不受任何特定编译器警告的约束,以下只是一个示例。

当前当我想要一个循环来检查内部的退出条件时:

 while( true ) {
    doSomething();
    if( condition() ) {
       break;
    }
    doSomethingElse();
}

我不能只用 Visual C++ 编写它 - 它会发出 C4127

conditional expression is constant
警告。编译器会在我面前挥舞它,尽管很明显
while(true)
不可能是意外写入的。

假设我想要编译时没有警告的代码。我可以为您提供解决方法

解决方法一是使用

for(;;)
,但感觉很愚蠢 - 为什么我想要那种奇怪的东西而不是简洁优雅的惯用语
while(true)
解决方法二是在
#pragma warning( suppress)
行之前使用
while( true )
,但它会添加一个巨大的横幅,其大小是
while
语句本身的两倍。 解决方法三是为整个项目禁用 C4127(我在实际项目中见过它),但随后 C4127 的所有可能有用的实例也被禁用。

有什么优雅的方法可以摆脱毫无意义的警告吗?

c++ compiler-warnings
7个回答
28
投票

我会写

for(;;)
,因为这是惯用语。

新版本的 Visual C++ 并不像早期版本那样白痴。警告。 Visual C++ 10.0 编译使用

<windows.h>
的代码,警告级别为 4,无警告。

但是,如果您想关闭 Visual C++ 愚蠢警告,请查看我旧的 anti-sillywarnings 标头,它是根据 [comp.lang.c++] 社区的输入创建的。


11
投票

即使没有那个警告,我也会选择

for(;;)
。这并不愚蠢:这是一个没有条件的循环,这正是你想要表达的。

对我来说,这似乎比使用 while 循环并在每次循环时测试 true 仍然为 true 更合乎逻辑(当然编译器会优化此测试,因此它实际上不会影响性能)。


6
投票

什么可以——实际可行——比一行更更优雅:

#pragma warning ( suppress : 4127 )

我不能使用这个,因为我仍在使用VS2005,这不适用于所有警告。)

当然,对于您的情况

for(;;)

可能是务实的方法,但总的来说

如何优雅地克服

毫无意义的 C++ 编译器警告?

我会说

禁用它们整个项目。 (毕竟没有意义)。并且,要改变

如何优雅地克服

误报 C++ 编译器警告?

我想说,一个

single 预处理器行似乎已经很不错了。


3
投票
我的理念是,如果你让编译器抑制警告,请在其中添加注释并说明原因。 即使你认为这很愚蠢。 Pragma 脱颖而出并且可见。 这是您代码中的一个很好的注释。

当你开始跳过评论并根据你的想法压制警告时,你正在走向潜在的麻烦。 一年后处理您的代码的另一个人可能会更改它,遇到麻烦并浪费宝贵的时间来寻找它。

顺便说一句,您正在寻找一种抑制警告的方法,而无需任何方法

    使用编译指示
  • 使用丑陋的代码
  • 使用项目范围的抑制
那将是一种非常隐蔽的压制手段。

如果您不喜欢杂注的外观,请使用

bool alwaysTrue = true; // to prevent compiler warning C4127 while (alwaysTrue) { ... }
    

0
投票
我使用 while(true, 1) 来抑制此警告。


-1
投票
做一些有趣的标记粘贴:如果你可以交换

while(true)

对于

While(true)

然后只需执行以下操作:

#define while_true for( ;; ) #define While(a) while_##a
    

-2
投票
在很多情况下,令人满意的代码按预期运行,但会生成大量警告。这就是为什么它们是“警告”而不是错误。他们惹恼你这一事实是好的:警告的目的是改变你的行为。你应该改正自己的行为,而不是把它们掩盖起来。

问题中的示例循环可以这样写:

for (; testExitCondition();) doSomething();

在更复杂的情况下,循环计数器可以用作状态机的状态(每个操作都需要更新
state
):

for (int state = stateBegin; state == stateTerminate;) { switch (state) { case stateBegin: //elaborate setup break; case state_1: doSomething_1(); break; case state_2: doSomething_2(); break; case state_n: doSomething_n(); break; }

我最喜欢避免无意义的 C++ 警告的方法是使用 C# :)

诚然,这会产生大量毫无意义的 C# 警告,但没有什么是完美的。

天哪,看看反对票。证明 C++ 会损害你的幽默感。

© www.soinside.com 2019 - 2024. All rights reserved.