循环中的C ++变量声明和运行时错误

时间:2014-03-09 00:06:52

标签: c++ visual-studio-2010 gcc visual-studio-debugging

我有一个在循环中声明的缓冲区。它在第一次迭代时初始化。我最近在Visual Studio 2010调试中运行了代码,它打破了运行时错误:
Run-Time Check Failure #3 - The variable 'buffer' is being used without being initialized.

以下是一些示例代码。 It's also available on ideone where it runs successfully.

using namespace std;
int main( int argc, char *argv[] )
{
    for( int i = 0; i < 5; ++i )
    {
        char buffer[5];
        if(i == 0)
        {
            buffer[0] = 'y';
            buffer[1] = '\0';
        }
        cout << buffer[0] << endl;
    }

    return 0;
}

我认为每次迭代都没有重新创建缓冲区。我知道如果我有一个向量或其他东西,每次迭代都会调用构造函数,但我认为C类型或POD类型(如果这是正确的短语)是不同的。

Visual Studio是正确的还是错误的,我有一堆地方,在循环的迭代n中有缓冲区被更改,我希望缓冲区在迭代之后相同,直到再次更改为止。他们在gcc中,但是在最近的调试会话中,我猜这只是运气!

由于

编辑:在codeguru上发现了一个有趣的主题,人们似乎对此有所分歧:
Variable declaration inside a loop

2 个答案:

答案 0 :(得分:3)

变量从声明的时间到声明它的作用域的末尾。你的编译器是对的。仅在循环的i == 0轮中,buffer变量被初始化(部分);在所有其他循环中,变量保持未初始化。

情况与此无异:

{
    int n = 10;
}

{
    int n;      // uninitialized
    cout << n;  // UB
}

答案 1 :(得分:1)

如果您希望变量在for循环中保留其值,则始终将其声明为外部。无论是班级还是POD。

最能表达您对编译器和软件维护人员的意图。 通过在for-loop中移动它几乎没有赢得任何东西。 如果您决定让每个人都知道此var仅用于for循环范围,那么您可以在其周围添加另一个范围。

using namespace std;
int main( int argc, char *argv[] )
{
    {
        char buffer[5];
        for( int i = 0; i < 5; ++i )
        {
            if(i == 0)
            {
                buffer[0] = 'y';
                buffer[1] = '\0';
            }
            cout << buffer[0] << endl;
        }
  }
  return 0;
}

考虑到某些编译器可能能够为您优化循环初始化,使代码不清楚。标准中也没有说明这种优化,因此编译器可以自由地不这样做。