1

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

2
  • Wonder how you got the idea of there being "special cases". All automatic variables are handled the same way, and that's a good thing. Commented Mar 9, 2014 at 0:17
  • When you have void f(int b) { int a = b; }, then there is an object created for the variable a every time you call the function. There's nothing special going on. Objects are dynamic concepts; variables are static concepts. Variables are in the source code, objects are in the running program. It's not a contradiction that a single variable declaration causes the life of many objects. Commented Mar 9, 2014 at 0:32

2 Answers 2

3

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
}
Sign up to request clarification or add additional context in comments.

5 Comments

I think your example is flawed. The reason the compiler tagged it as not initialized is because of the if statement.
@CaptainGiraffe: I don't understand. The reason the compiler tagged it as uninitialized is because it's uninitialized.
The difference is, OP's code could be valid if the semantic check would include runtime consequences.
@CaptainGiraffe: The OP's code is never valid. The compiler is right.
True, but his confusion is valid. Unfortunately I am not able to provide a better answer.
1

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.

1 Comment

Thank you for your example. The other poster gave a correct answer first so I've marked his answer as correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.