简体   繁体   English

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

[英]C++ variable declaration in a loop and runtime error

I have a buffer that is declared in a loop. 我有一个在循环中声明的缓冲区。 It is initialized on the first iteration. 它在第一次迭代时初始化。 I recently ran the code in Visual Studio 2010 debug and it breaks on a runtime error: 我最近在Visual Studio 2010调试中运行了代码,并且由于运行时错误而中断:
Run-Time Check Failure #3 - The variable 'buffer' is being used without being initialized.

Here is some sample code. 这是一些示例代码。 It's also available on ideone where it runs successfully. 它也可以在成功运行的ideone上使用。

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;
}

I thought that the buffer wasn't recreated on every iteration. 我认为并不是每次迭代都重新创建缓冲区。 I know that if I had a vector or something the constructor would be called on every iteration but I thought C types or POD types (if that's the right phrase) were different. 我知道,如果我有一个向量或某种东西,那么每次迭代都会调用构造函数,但我认为C类型或POD类型(如果那是正确的短语)是不同的。

Is Visual Studio correct or is it wrong, I have a bunch of places where there are buffers that are changed on iteration n of a loop and I expected that buffer to be the same on iterations after that until changed again. 是Visual Studio正确还是错误,我在很多地方都有在循环的迭代n处更改的缓冲区,我希望在此之后的迭代中该缓冲区是相同的,直到再次更改。 And they are in gcc but with this recent debug session I'm guessing that's just luck! 而且它们在gcc中,但是在最近的调试会话中,我想这很幸运!

Thanks 谢谢

edit: Found an interesting thread on codeguru where people seem to be split about it: 编辑:在codeguru上发现了一个有趣的话题,人们对此似乎有所分歧:
Variable declaration inside a loop 循环内的变量声明

The variable lives from the time it's declared to the end of the scope in which it is declared. 变量从声明的时间到声明的作用域的结尾一直存在。 Your compiler is right. 您的编译器是正确的。 Only in the i == 0 round of the loop is the buffer variable initialized (partially); 仅在循环的i == 0轮中才初始化(部分) buffer变量; in all the other loops, the variable remains uninitialized. 在所有其他循环中,变量保持未初始化状态。

The situation is no different from this one: 情况与此无异:

{
    int n = 10;
}

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

If you want a variable to retain its value across a for loop, you should always declare it outside. 如果希望变量在for循环中保留其值,则应始终在外部声明它。 Regardless whether it is a class or a POD. 无论是类还是POD。

That best expresses your intention to the compiler and to your fellow software maintainers. 这最能向编译器和其他软件维护人员表达您的意图。 You win practically nothing by moving it inside the for-loop. 通过将其移入for循环,您几乎一无所获。 If you are determined on letting everyone know that this var is only used in the for loop scope, then you can add another scope around it. 如果您决定让每个人都知道此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;
}

Taking into account that some compilers may be able to optimize the initialization out of the loop for you, makes the code unclear. 考虑到某些编译器可能能够为您优化循环外的初始化,因此使代码不清楚。 Also this optimization is not stated in the standard, so compilers are free to not do that. 此外,该优化未在标准中进行说明,因此编译器可以自由地做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM