1

I am learning C++ using Robert Lafore's book ( OOP with C++ ). In the book, I have encountered this example:

#include <iostream>
#include <conio.h>

using namespace std;

void main ()
{
    int numb;

    for ( numb = 1 ; numb <= 10 ; numb++ )
    {
        cout << setw(4) << numb;
        int cube = numb*numb*numb;
        cout << setw(6) << cube << endl;
    }

    getch();
}

The variable 'cube' has been declared as int 'inside the loop body'.

int cube = numb*numb*numb;

Since the loop iterates 10 times, the variable 'cube' will also get declared 10 times. 'cube' is accessible inside the loop body no matter what iteration. So, when we enter the loop body for, say, 2nd iteration, 'cube' is already known( because it already got declared during the 1st iteration), and another declaration for 'cube' should give an error of "redefinition". But instead, it builds successfully and debugs without a problem. Why?

olevegard
  • 5,294
  • 1
  • 25
  • 29
ColorDeColor
  • 181
  • 2
  • 12

7 Answers7

15

The scope of an automatic variable (such as cube) is the block in which it is declared. The block that cube is declared in is the body of the for loop. At the end of each iteration, the cube variable goes out of scope, the next iteration starts and then cube is introduced to the scope again. Logically, there is no clash because no two identifiers cube exist in the same scope - in fact, there is only a single declaration of cube.

It might be worth distinguishing between the declaration of a variable and the creation of an object due to that declaration. There is only one declaration int cube = ...;. It doesn't matter that this piece of code may be reached many times; it's still only one declaration. The rules of the language say that you cannot declare two variables with the same name in the same scope, but that's okay since you're only declaring it once. This is a completely static rule that your compiler is able to analyse.

It just so happens that your declaration is reached 10 times because of your for loop, which means that 10 int objects will be created. Due to the scope of the variable, they won't all exist at the same time. This is not a static property of the program. The compiler cannot in general know beforehand how many times a line of code will be reached.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • I used the watch window to keep track of the variables. Everytime the control of the program re-entered the loop body, the variable 'cube' was already known before even reaching the statement int cube = numb*numb*numb; – ColorDeColor Feb 11 '14 at 10:08
  • So, as I understand it, although 'cube' vanishes at the end of every iteration, it automatically re-establishes when the body is re-entered. So, a deliberate definition of 'cube' inside the body should give an error, shouldn't it? – ColorDeColor Feb 11 '14 at 10:10
  • @user3296146 I added more to my answer. If you have two `int cube` declarations in the same scope, you will get an error. – Joseph Mansfield Feb 11 '14 at 10:13
  • You used the term "automatic variable". What does it mean? – ColorDeColor Feb 11 '14 at 10:19
  • @user3296146 It is used to refer to variables that introduce objects with automatic storage duration. An automatic object is destroyed automatically at the end of its scope. Alternative storage durations are dynamic, static, and thread. – Joseph Mansfield Feb 11 '14 at 10:21
  • @JosephMansfield Thank you! I think I get your point, though I still need to ponder over it a bit more :) Also, u said a new object of the variable is created in every iteration. Is the new object created at the same or differnt location in memory? – ColorDeColor Feb 11 '14 at 10:26
  • @user3296146 That is not specified by the language, but any sane compiler will just reuse the same storage location for the object. – Joseph Mansfield Feb 11 '14 at 10:27
  • @Spook Sure! I was so immersed in Joseph's answer, i forgot i could look that up myself. – ColorDeColor Feb 11 '14 at 10:28
  • @JosephMansfield alright! I get your point overall! I'll ponder over it, and if I get confused , i'll comment here :) – ColorDeColor Feb 11 '14 at 10:31
  • @user3296146 Of course, this loop could be in some other function `foo` which is called in many places. Across different calls of `foo`, the `cube` object may be placed at various different memory locations. I'm just saying that each object introduced in a single set of iterations of the loop will likely have the same memory location. – Joseph Mansfield Feb 11 '14 at 10:35
8

When you enter the loop a 2nd time, the first cube has gone out of scope so it's all OK.

Two cubes in the same scope would be a problem:

{
    int cube = 0;
    int cube = 1;
}
doctorlove
  • 18,872
  • 2
  • 46
  • 62
6

You've discovered "Automatic-storage duration".

The variable cube is declared inside the loop. Especially, inside the block-scope of the loop. At the end of the loop, this variable will be destroyed, just like any variable declared in any block-scope, be it a function, a loop, an if/else block, or just a raw block scope that you can declare anywhere in the code using { and }, i.e.:

int main(){

    //Beginning of block
    {
        int cube = 1;
        //cube exists and is declared here
    }//End of block

    //cube is gone here

    return 0;
}

So in fact, every iteration of the loop will have its brand new and fresh cube variable.

JBL
  • 12,588
  • 4
  • 53
  • 84
  • "So in fact, every iteration of the loop will have its brand new and fresh cube variable", you said. But i used the watch window, and every time i re-entered the loop body, the watch window showed 'cube' before reaching the line (int cube = numb*numb*numb;), and that too with the same value with which it left the previous iteration. – ColorDeColor Feb 11 '14 at 10:15
  • @user3296146 compilers are allowed to optimize such things as long as the resulting code behaves as if the variable had been declared as described. As your code has no observable side effects, there is no reason for not optimizing. You may want to repeat the experiment with a more complex object with constructor and destructor. – Hulk Feb 11 '14 at 10:55
5

The variable cube is only used inside the body of the for loop. I am not sure that saying it is declared ten times is correct (a declaration, actually a definition in your case, is a syntactic and static textual portion of source code).

In C++ you can (and you often do) have blocks with local variables. The scope of cube starts at it declaration and ends at the end of the containing block (braces { ... }).

If the type of a defined variable has a constructor, it is called at the definition point. If that type has a destructor, it is called conceptually at the end of the block (figuratively, just before the closing } ....).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I like how you explained it using "constructors" and "destructors". It solidified my understanding of these terminologies and answered my question as well from a different perspective. – ColorDeColor Feb 11 '14 at 11:42
  • 1
    It's *definitely* declared once, because declaration refers to the source code, not runtime. I think, we can say, that it's *instantiated* ten times (automatically, on the stack). – Spook Feb 12 '14 at 07:40
2

The variable will be declared in each iteration of the loop, and then it will go out of scope as the block ({...}) ends, i.e. it will cease to exist. Then on the next iteration it will be declared again, which is not a redeclaration, since it didn't exist. It is said to be a "local variable", in this case local to the block.

Biffen
  • 6,249
  • 6
  • 28
  • 36
1

As cube is defined inside the cycle body its scope will be that body. So after each iteration completes cube will go out of scope and on the next iteration a brand new cube will be created. This is what happens in theory. It may happen though that the compiler optimizes this code and only ever creates one variable. Either way the code is perfectly valid and will work as excepted.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
0

The variable 'cube' is declared and defined in each iteration. The scope of 'cube' dies with the iteration and new declaration and definition in each loop happens.

Subhajit
  • 320
  • 1
  • 6