是'警告C4127`(条件表达式是不变的)有用吗?

Moh*_*ain 17 c c++ visual-c++ c4127

回答这篇文章时,我建议使用do {...} while(0)多行宏.

在MSVC上,我发现此代码抛出:

warning C4127: conditional expression is constant
Run Code Online (Sandbox Code Playgroud)

为了使代码无警告,我需要选择以下丑陋的替代方案之一:

选项1

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4127)
#endif
code_using_macro_that_generates_C4217;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
Run Code Online (Sandbox Code Playgroud)

选项2
将我的宏定义为:

#define MULTI_LINE_MACRO do { ... } while(0,0)
Run Code Online (Sandbox Code Playgroud)

要么

#define MULTI_LINE_MACRO do { ... } while((void)0,0)
Run Code Online (Sandbox Code Playgroud)

一些程序员也称它为"猫头鹰",(0,0)看起来像一只猫头鹰.

选项3
定义一个新的宏WHILE_0,它不会生成警告而是使用它而不是while(0)

问题
我相信所有选择都或多或少都是可怕的.为什么MSVC会为看似正确的代码生成此警告,并激励我在代码中添加一些丑陋以保持代码警告免费?

我相信条件中的常量表达式是完全有效的,特别是在基于编译器优化代码的能力的构造中.

此外,我没有得到warning C4127像这样的代码:

void foo(unsigned bar)
{
    while (bar >= 0)
        ;
} 
Run Code Online (Sandbox Code Playgroud)

我的问题是:是不是warning C4127: conditional expression is constant完全没用,是不是它激发了丑陋的代码?这个警告是否有助于编写更好的代码?

maf*_*fso 5

我不认为它有用.相反,有更多的误报而不仅仅是do .. while(0)成语.想想像这样的结构

if(sizeof(long) == 8) { /* ... */ }
if(SOME_CONSTANT_MACRO) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

前者不能被#if指令取代,后者可以,但是一些编码风格指南更喜欢if版本,因为仍然对死代码进行语法检查(在其他平台或其他编译时配置中没有死)并且有些找不到它更好阅读.

警告(除了标准所要求的警告之外,其中大多数应被视为错误)通常是针对有效但可能做其他事情的代码而发出的.if(0)或者像这样的东西看起来很傻,但看起来不像"语法检查这个否则死代码"之外的东西.它可能会困扰读者,但它是明确的,我不知道这是如何偶然发生的.

从目前给出的示例(我没有自己的MSVC进行测试),似乎警告是针对C语言意义上的常量表达式(也就是说,不是可以是常量折叠但是语法上的东西不是一个常量表达式),因此它不会被发射出来if(array),或者if(function)(例如gcc -Wall,警告,因为它可能是一个函数调用).

while(0,0)更糟糕的是,在我看来,它触发了一个警告gcc -Wall,一个逗号操作员的左侧没有副作用,我可以想象偶尔有用的警告(通常很容易避免).这个警告随着消失而消失while((void)0,0).

我建议关闭警告.