什么是&QUOT可能使用;#定义为,如果(假){}用于其他与QUOT ;? [英] What is the possible use for "#define for if (false) {} else for"?

查看:175
本文介绍了什么是&QUOT可能使用;#定义为,如果(假){}用于其他与QUOT ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在另外一个问题,我刚刚发现的 C 智慧这个小珍珠:

In another question, I just spotted this little pearl of C wisdom:

#define for if (false) {} else for

造成MSVC吐出一个相当有效的语句不断前pression警告:

which caused MSVC to spit out "constant expression" warnings for a quite valid statement:

for (int i = 0; i <= 10; i++) {...}

我理解的为什么的MSVC的抱怨,因为它扩展为:

I understand why MSVC is complaining because it expands to:

if (false) {} else for (int i = 0; i <= 10; i++) {...}

我只是不明白,为什么开发者使用的小片段。任何人都有一个想法?

I just don't understand why the developers would use that little snippet. Anyone have an idea?

推荐答案

这是修复一个bug在旧版本的Visual C ++的(V6.0和更早版本)。在过去,VISUAL C ++打破了关于宣布在声明变量的作用域的规则:

It's to fix a bug in old versions of Visual C++ (v6.0 and earlier). In the past, Visual C++ had broken scope rules about variables declared inside for statements:

// This compiles in old versions of Visual C++, but it is in fact INVALID C++
for(int i = 0; ...)
{
    ...
}

for(i = 0; ...)
{

}

在换句话说,VISUAL C ++提供了 I ,就好像它被宣布为外循环,它可以让你继续使用它的循环完成后范围。这导致code,如上面的代码片段。在更符合标准的编译器, I 的范围不再在第二循环的定义,因此,编译器发出关于错误我被定义。

In other words, Visual C++ gives i a scope as if it were declared outside the loop, and it lets you continue using it after the loop is done. This lead to code such as the above snippet. In more standards-compliant compilers, i is no longer in scope at the definition of the second for loop, so the compiler issues an error about i being undefined.

要解决这个问题,有些人使用这个宏(或非常相似,相当于宏):

To fix this, some people used this macro (or very similar, equivalent macros):

#define for if(0) {} else for

这改变了循环到这一点:

This changes the for loop into this:

if(0)
{
}
else
    for(int i = 0; ...)
    {
        ...
    }

这会将循环到范围额外的水平,所以,在循环中声明的变量会出事后范围,无论VISUAL C ++的错误。这可以确保在同一code一贯正确编译在这两个Visual C ++和符合标准的编译器,以及不正确的code不正确一致编译。

This puts the for loop into an extra level of scope, so that any variables declared in the for loop will be out of scope afterwards, regardless of Visual C++'s bug. This makes sure that the same code compiles correctly consistently in both Visual C++ and standards-compliant compilers, and that incorrect code does not compile correctly consistently.

另外请注意,如果宏被定义,而不是如此:

Also note that if the macro were instead defined as so:

// DO NOT USE
#define for if(1) for

然后尽管这对一些简单的code相同的效果,它会突然导致以下code不正确地编译:

Then although that would have the same effect for some simple code, it would suddenly cause the following code to be compiled incorrectly:

if(foo)
    for(...)
    {
        ...
    }
else
    doSomething();

由于如果展开宏,你会得到这样的:

Because if you expand the macro, you get this:

if(foo)
    if(1)
        for(...)
        {
            ...
        }
    else
        doSomething();

以及其他现在用错相匹配如果!所以,巧妙地利用使用如果(0){}其他而不是,如果(1)避免了这个问题。

And the else now matches up with the wrong if! So, the clever use of using if(0) {} else instead of if(1) avoids this problem.

最后要注意,因为如果(0){}其他为不会导致无限递归,因为preprocessor不会递归取代宏的#define您当前定义。它只会做这个问题的一个替代品。

As a final note, #define for if(0) {} else for does not cause infinite recursion, because the preprocessor will not recursively replace the macro which you are currently defining. It will only do one replacement in this case.

这篇关于什么是&QUOT可能使用;#定义为,如果(假){}用于其他与QUOT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆