Reputation: 1074
Let's look at the following piece of code which I unintentionally wrote:
void test (){
for (int i = 1; i <=5; ++i){
float newNum;
newNum +=i;
cout << newNum << " ";
}
}
Now, this is what I happened in my head: I have always been thinking that float newNum would create a new variable newNum with a brand-new value for each iteration since the line is put inside the loop. And since float newNum doesn't throw a compile error, C++ must be assigning some default value (huhm, must be 0). I then expected the output to be "1 2 3 4 5". What was printed was "1 3 6 10 15".
Please help me know what's wrong with my expectation that float newNum would create a new variable for each iteration?
Btw, in Java, this piece of code won't compile due to newNum not initialized and that's probably better for me since I would know I need to set it to 0 to get the expected output.
Upvotes: 0
Views: 437
Reputation: 3856
I don't do too much C++ since last month, but:
The float values is newly allocated for each iteration. I'm a bit surprised about the initial zero value, though. The thing is, after each iteration, the float value runs out of scope, the next step (the reenter of the loop scope) first reallocates the float memory and this will often return the same memory block that was just freed.
(I'm waiting for any bashing :-P)
Upvotes: 0
Reputation: 26419
C++ must be assigning some default value (huhm, must be 0).
C++ doesn't initialize things without default constructor (it may set it to something like 0xcccccccc on debug build, though) - because as any proper tool, compiler "thinks" that if you haven't provided initialization then it is what you wanted. float doesn't have default constructor, so it is unknown value.
I then expected the output to be "1 2 3 4 5". What was printed was "1 3 6 10 15".
Please help me know what's wrong with my expectation that float newNum would create a new variable for each iteration?
Variable is a block of memory. In this variable is allocated on stack. You didn't initialize it, and each iteration it just happen to be placed on the same memory address, which is why it stores previous value. Of course, you shouldn't rely on such behavior. If you want value to persist across iterations, declare it outside of loop.
Btw, in Java, this piece of code won't compile due to newNum not initialized
BTW, in C++ normal compiler would give you a warning that variable is not initialized (Example: "warning C4700: uninitialized local variable 'f' used"). And on debug build you would get crt debug error (Example: "Run-Time check failure #3 - The variable 'f' is being used without being initialized").
and that's probably better
Negative. You DO need uninitialized variables from time to time (normally - to initialize them without "standard" assignment operator - by passing into function by pointer/reference, for example), and forcing me to initialize every one of them will be a waste of my time.
Upvotes: 0
Reputation: 92864
Using garbage value in your code invokes Undefined Behaviour in C++. Undefined Behavior means anything can happen i.e the behavior of the code is not defined.
float newNum; //uninitialized (may contain some garbage value)
newNum +=i; // same as newNum=newNum+i
^^^^^
Whoa!!
So better try this
float newNum=0; //initialize the variable
for (int i = 1; i <=5; ++i){
newNum +=i;
cout << newNum << " ";
}
Upvotes: 0
Reputation: 116266
Since newNum
is not initialized explicitly, it will have a random value (determined by the garbage data contained in the memory block it is allocated to), at least on the first iteration.
On subsequent iterations, it may have its earlier values reused (as the compiler may allocate it repeatedly to the same memory location - this is entirely up to the compiler's discretion). Judging from the output, this is what actually happened here: in the first iteration newNum
had the value 0 (by pure chance), then 1, 3, 6 and 10, respectively.
So to get the desired output, initialize the variable explicitly inside the loop:
float newNum = 0.0;
Upvotes: 6
Reputation: 68765
C++ must be assigning some default value (huhm, must be 0)
This is the mistake in your assumptions. C++ doesn't attempt to assign default values, you must explicitly initialise everything.
Most likely it will assign the same location in memory each time around the loop and so (in this simple case) newNum will probably seem to persist from each iteration to the next.
In a more complicated scenario the memory assigned to newNum would be in an essentially random state and you could expect weird behaviour.
http://www.cplusplus.com/doc/tutorial/variables/
Upvotes: 2
Reputation: 936
You might have got your expected answer in a debug build but not release as debug builds sometimes initialise variables to 0 for you. I think this is undefined behaviour - because C++ doesn't auto initialise variables for you, every time around the loop it is creating a new variable but it keeps using the same memory as it was just released and doesn't scrub out the previous value. As other people have said you could have ended up with complete nonsense printing out.
It is not a compile error to use an uninitialised variable but there should usually be a warning about it. Always good to turn warnings on and try to remove all of them incase something nastier is hidden amongst them.
Upvotes: 0
Reputation: 25166
You are using an uninitialized automatic stack variable. In each loop iteration it is located at the same place on the stack, so event though it has an undefined value, in your case it will be the value of the previous iteration.
Also beware that in the first iteration it could potentialliay have any value, not only 0.0
.
Upvotes: 0
Reputation: 1313
The mistake in thoughts you've expressed is "C++ must be assigning some default value". It will not. newNum contains dump.
Upvotes: 0
Reputation: 13972
The float you are creating is not initialised at all. Looks like you got lucky and it turned out to be zero on the first pass, though it could have had any value in it.
In each iteration of the loop a new float is created, but it uses the same bit of memory as the last one, so ended up with the old value that you had.
To get the effect you wanted, you will need to initialise the float on each pass.
float newNum = 0.0;
Upvotes: 1