質問

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:
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.

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.

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. And they are in gcc but with this recent debug session I'm guessing that's just luck!

Thanks

edit: Found an interesting thread on codeguru where people seem to be split about it:
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); 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. Regardless whether it is a class or a 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. 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.

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帰属
所属していません StackOverflow
scroll top