8

关于无限循环的编码风格问题中,有些人提到他们更喜欢 for(;;) 风格,因为 while(true) 风格会在 MSVC 上给出关于条件表达式为常数的警告消息。

这让我非常惊讶,因为在条件表达式中使用常量值是避免#ifdef 地狱的有用方法。例如,您可以在标题中包含:

#ifdef CONFIG_FOO
extern int foo_enabled;
#else
#define foo_enabled 0
#endif

并且代码可以简单地使用条件并信任编译器在未定义 CONFIG_FOO 时删除死代码:

if (foo_enabled) {
    ...
}

不必每次使用 foo_enabled 时都测试 CONFIG_FOO:

#ifdef CONFIG_FOO
if (foo_enabled) {
    ...
}
#endif

这种设计模式一直在 Linux 内核中使用(例如,include/linux/cpumask.h 在禁用 SMP 时将多个宏定义为 1 或 0,在启用 SMP 时定义为函数调用)。

MSVC 警告的原因是什么?此外,有没有更好的方法来避免 #ifdef 地狱而不必禁用该警告?或者它是一个过于宽泛的警告,一般不应该启用?

4

4 回答 4

10

警告并不意味着代码很糟糕,只是看起来很可疑。

就我个人而言,我从启用所有可能的警告的位置开始,然后关闭任何被证明比有用更烦人的警告。每当您将任何内容转换为布尔值时都会触发的那个通常是第一个触发的。

于 2008-10-22T03:57:48.450 回答
5

我认为警告的原因是你可能无意中有一个更复杂的表达式,它在没有意识到的情况下计算为一个常量。假设您在标题中有这样的声明:

const int x = 0;

然后稍后,远离 x 的声明,您有一个条件,例如:

if (x != 0) ...

您可能没有注意到它是一个常量表达式。

于 2008-10-22T03:54:11.890 回答
2

我相信这是为了抓住像

 if( x=0 )

当你的意思是

 if( x==0 )
于 2008-10-22T03:49:43.740 回答
0

避免警告的一种简单方法是:

#ifdef CONFIG_FOO
extern int foo_enabled;
#else
extern int foo_enabled = 0;
#endif
于 2008-10-22T03:53:16.477 回答