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

时间:2011-11-15 08:47:32

标签: c++ compiler-construction compiler-warnings

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

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

 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的所有可能有用实例也被禁用。

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

7 个答案:

答案 0 :(得分:28)

我写for(;;),因为这是惯用的。

较新版本的Visual C ++并不像早期版本那样白痴。警告。 Visual C ++ 10.0编译使用<windows.h>的代码,警告级别为4,没有警告。

但是如果你想关闭Visual C ++傻瓜警告,看一下我的旧anti-sillywarnings header,它是用[comp.lang.c ++]社区的输入创建的。

答案 1 :(得分:11)

即使没有这个警告,我也会选择for(;;)。这不是愚蠢的:它是一个没有条件的循环,这正是你想表达的。

对我而言,这似乎比使用while循环更合乎逻辑并且每次循环测试都是真的(当然编译器会优化掉这个测试,所以它实际上不会影响性能)。

答案 2 :(得分:6)

什么可以 - 实际可实现 - 更多优雅的单行:

 #pragma warning ( suppress : 4127 )

我不能使用它,因为我仍然在VS2005上doesn't work for all warnings。)

当然,对于你的案例for(;;)可能是务实的方法,但总的来说是

  

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

我会说disable them project wide。 (毕竟没有意义)。并且,变化

  

如何优雅地克服 false-positve C ++编译器警告?

我会说,单个预处理器行似乎已经很好了。

答案 3 :(得分:3)

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

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

顺便说一下,你正在寻找一种在没有

的情况下抑制警告的方法
  • 使用pragma
  • 使用难看的代码
  • 使用项目范围抑制

这将是一种非常隐蔽的抑制方法。

如果你不喜欢pragma的外观,请使用

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

答案 4 :(得分:0)

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

答案 5 :(得分:-1)

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

while(true)

While(true)

然后只需执行以下操作:

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

答案 6 :(得分:-2)

在许多情况下,令人满意的代码按预期运行,但会产生大量警告。这就是他们警告而不是错误的原因。他们惹恼你的事实是好的:警告旨在改变你的行为。你应该修补你的方式,而不是把它们扫到地毯下。

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

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

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

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 ++会损害你的幽默感。