【问题标题】:odd "warning C4127: conditional expression is constant" under VS2005VS2005下奇怪的“警告C4127:条件表达式是常数”
【发布时间】:2009-06-11 23:05:13
【问题描述】:

我正在尝试编译 LightZPng 并在级别 4 上出现警告。我在明显不值得此警告的行上得到了很多 C4127。一个例子:

#define MAX_BITS 15
int values_per_bitlen[ MAX_BITS + 1 ];
for ( int i = 0; i <= MAX_BITS; ++i )    // C4127 is here
    values_per_bitlen[ i ] = 0;

如何更改此代码以避免#pragma 以外的警告?

【问题讨论】:

    标签: visual-studio-2005 compiler-warnings c4127


    【解决方案1】:

    LightZ.cpp 顶部有一段代码如下所示:

    #define for if (false) {} else for
    

    这意味着你的实际陈述是:

    #define for if (false) {} else for ( int i = 0; i <= MAX_BITS; ++i )
    

    这就是您收到常量表达式错误的原因(它是 false,而不是我想的 i &lt;= MAX_BITS)。

    只需注释掉或从文件中删除该行(我实际上无法弄清楚他们为什么要这样做)。

    【讨论】:

    • 好消息,@WinProg,为您充实并为它 +1。
    • 也许这需要进一步解释?这会导致每次后续出现的标记 for 扩展为包含 for 语句的 if 语句。 VC++ 将 if (false) 诊断为具有常量条件表达式,这不是开玩笑。如果删除这一行,程序中出现的if(false)就会减少。
    • “#define for”的原因是旧版本的 Visual Studio 在 for 循环中破坏了变量范围:如果您说 for(int i = 0; ...),则变量“ int i" 在循环结束后仍然存在。 #define 添加了一个额外级别的范围,解决了问题,因此执行“for(int i = 0; ...) ...; for(i = 0; ...)”的代码不再编译 (因为它不应该)。
    • 如果我没记错的话,旧版本的 C++ 语言正是这样定义了 for 变量的范围。
    【解决方案2】:

    是的,这很奇怪。它确实不是一个常量表达式,因为i 在循环中发生了变化。所以这似乎是VS2005的问题。就其价值而言,VS2008 做的完全一样。

    奇怪的是,一个带有 just this 的项目并没有抱怨,所以它很可能是微软警告生成代码的一些奇怪的边缘情况问题:

    #define MAX_BITS 15
    int values_per_bitlen[ MAX_BITS + 1 ];
    int main(int argc, char* argv[]) {
        for ( int i = 0; i <= MAX_BITS; ++i )
            values_per_bitlen[ i ] = 0;
        return 0;
    }
    

    但是,您实际上并没有提出任何问题。您想知道或希望我们做什么?

    更新:

    有关实际原因,请参阅“Windows 程序员”的答案 - LightZ.cpp 顶部有一个 "#define for if (false) {} else for" 导致问题。

    【讨论】:

    • 添加了一个问题..只是基本上想更改代码以避免警告而不实际关闭警告。
    • 您要更改代码吗?删除我在回答中引用的那一行。
    【解决方案3】:

    我在我的 VS2005 上测试过,警告没有出现,即使是在警告级别 4。..

    一个简单的程序供您遵循:

    -新建一个Console App,只放置上面的代码,看看是否再次出现警告。

    -如果不是,请检查项目设置中的差异。

    -如果是,我会假设您的优化设置可能会导致它。

    【讨论】:

    • 是的,一些项目设置告诉 VC++ 检查 if (false) 之类的内容,而一些项目设置告诉 VC++ 不检查 if (false) 之类的内容。
    【解决方案4】:

    According to Charles Nicholson,Visual Studio 2005 使用“do...while(0)”技巧给出此错误:

    #define MULTI_LINE_MACRO \
        do { \
            doSomething(); \
            doSomethingElse(); \
        } while(0)
    

    如果您绝对必须,您可以使用 __pragma 指令选择性地禁用特定代码片段周围的警告。

    【讨论】:

    • 它也给出了 if (false) 的警告,正如我们在这个问题中看到的那样。
    猜你喜欢
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 2014-05-16
    • 2013-06-14
    • 2012-03-04
    • 2011-12-08
    • 1970-01-01
    相关资源
    最近更新 更多