For循环在自己的花括号内


117

我遇到了这种for循环布局:

#include <iostream>
int main()
{
    {
        for (int i = 0; i != 10; ++i)
        {
            std::cout << "delete i->second;" << std::endl;
        }
    }

    {
        for (size_t i = 0; i < 20; ++i)
        {
            std::cout << "delete m_indices[i];" << std::endl;
        }
    }
    return 0;
}

我想知道这多余的括号是干什么用的?这在我们的代码库中出现了几次。


47
在您发布的代码段中,它们完全是多余的
EdChum

25
哪些编译器已与此代码一起使用?特别是VS 6被使用了吗?
UKMonkey

5
@EdNorman现在可以更轻松地进行编辑了。似乎正确的答案是UKMonkey提供的答案。使用现代C ++编译器,您可以简单地删除花括号。
Jabberwocky

8
另外,也可以生成代码(有人对狂想曲
感到grip异

4
一个可能的原因是该代码是否曾经(或将来打算)拥有OpenMP并行指令。
jamesqf

Answers:


286

曾几何时,许多月前,VS6存在并广受欢迎。但是,它未能符合许多C ++标准。在标准正式发布之前(同年)发布时,这是合理的;据我所知,它确实遵守了标准草案。

在草案和正式标准之间更改的标准之一是在第一部分中创建的for循环变量的生存期。导致以下代码无法编译

{
    for (int i=0; i<1; ++i){}
    for (int i=0; i<2; ++i){}
}

因为i已由第二个for循环重新定义。

其他编译器也遇到了此错误;我重点介绍VS6,因为它是标准发布后许多年以来Visual Studio的唯一版本,但从未针对此特定问题发布更新。意味着它产生了更大的影响。

一种解决方案是将整个for循环强制进入其自己的作用域,如您所示。


49
无需找到VS6即可看到@bolov,在VS2015中将“ For Loop范围内的“强制符合性””设置为“否”,并享受;-)
alain

5
@alain“选项'Zc:forScope-'已被弃用,将在以后的版本中删除”,并且可以毫无问题地进行编译...我很遗憾
bolov

7
2.7版之前的GCC也表现出这种行为。请参阅docs.freebsd.org/info/g++FAQ/g++FAQ.info.for_scope.html
Jeremy

5
@Damon并不是VS6第一次发布的时候。但是,当标准更改时,从未发布符合标准的更新。更改标准后,VS6流行了好几年。
UKMonkey

7
将其归因于旧的Microsoft编译器是一种错误。此行为实际上是C ++标准草案的功能,许多编译器都这样做(不仅是Microsoft编译器)。从内存来看,在1995年左右的草案中对其进行了更改,以使变量在循环中局部存在-大约在第一个C ++标准获得批准的三年之前。因此,大多数早于1996年的C ++编译器都以这种方式工作。
彼得

15

{}会创建一个范围,如果您在范围中定义了一些变量,则无法从外部访问它们。但是for已经创建了该范围。所以

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

是相同的

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

但是,如果您在两者之间定义一些东西,那会有区别

{int a = 0; for(int i = 0; i < count; ++i){}}

在此示例中,a无法从外部范围访问。


2

在您的特定示例中,没有理由使用它们。

有时您可能想为变量创建范围:

float average;
// ...

{
int sum = 0;
for (int i = 0; i < count; ++i)
{
   sum += v[i];
}
average = (float)sum / count;
}

// use average
// sum not in scope here

但是,我认为这是一种反模式。通常,如果您发现自己需要这样做,那么很可能for应该是它自己的功能。


好的,如果您认为它应该在其自身的功能中(我可以想到很多次这只会至少增加开销,但我不会去那里),这是一个假设的问题:如果您需要一个交换机案例的特定本地范围?当然,有时需要添加一个额外的作用域(当然函数也可以这样做)(请注意,对于您的示例,我[根本不认为单独的函数是个坏主意),但有时甚至不是那么简单还有其他方法。
Pryftan

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.