Visual C++,使用相同迭代器名称的多个for循环,在调试模式下在范围外可见

Visual C++, multiple for loops using same iterator name, visible outside of scope in debug mode

本文关键字:调试 for 循环 模式 范围 C++ 迭代器 Visual      更新时间:2023-10-16

我使用的是Visual Studio Express 2013,有多个for循环,其中迭代器使用相同的名称,如下所示:

for (int i = 0; i < 10; i++) {
  // do something
}
....
for (int i = 0; i < 10; i++) {
  // do something else
}

当我在调试模式下逐步完成时,在离开第一个for循环后,第一个"I"在Locals窗口中的最终值10仍然可见,即使它已经超出了范围。然后我进入第二个for循环,现在我显示了两个I(尽管值不同)。这有点烦人,因为我会在另一个条件下打断某个地方,并且我不能立即看到I的值是什么。我可以通过在迭代器范围外声明一次"I"来解决这个问题:

int i;
...
for (i = 0; i < 10; i++) {
  // do something
}
...
for (i = 0; i < 10; i++) {
  // do something else
}

但它仍然困扰着我,因为它看起来不一致。我希望看到与此相同的行为,第一个"I"一旦超出范围,就会从Locals窗口中消失:

{
  int i = 0;}
}
...
{
  int i = 1;
}

我想知道这是否只是微软的事情,或者我是否没有正确理解循环的作用域。。。

漂亮的接球。

对我来说,这听起来或多或少像是一个编译器错误。VC中有一个选项可以选择"强制循环范围内的一致性",这样For循环变量就超出了For循环之外的范围。

但是,这并不能解决您在调试器中提到的问题。无论您选择哪一个选项,调试器中都有这两个变量,这似乎很令人困惑。

区分它们的唯一方法是,范围外的i在调试模式下应该具有值0xcccccccc。这应该是特定于编译器的,WinDbg以不同的方式处理它,如下文所述。

我尝试过的:VC2008、VC2012

有一篇很好的文章很好地试验了这个问题。

MSVC有一个特殊的编译器标志,它可以影响示例中int i的作用域:/Zc:forScope。

默认情况下它是打开的,但调试器的设置可能是为了适应使用/Zc:forScope关闭它-将使以下代码有效(即使它不符合标准):

{
    for (int i=0; i < 10; ++i)
    {
        // Do something
    }
    for(i=0; i < 10; ++i)
    {
        // Do something else
    }
}

或者,如果您不小心关闭了它,那么您的代码并不像您(和C++标准)所期望的那样工作,但您可能会在重新声明i时收到警告。

Visual Studio中有一个选项,用于控制在for循环中定义的变量范围是否在for循环之外可见。它被称为/Zc:forScope。当您使用/Zc:forScope-时,您会得到您所描述的行为。要更改行为以符合C++标准,必须使用/Zc:forScope

更多信息可以在MSDN网站上找到:/Zc:forScope(循环作用域中的强制一致性)。