Why are we allowed to redeclare the same variable inside of a loop?

I know that if you declare a variable and then later in your code you try to declare a new variable with the same name you will get an error because you can't redeclare a variable. I understand why this example returns an error:

1
2
3
4
5
6
7
8
9
10
#include<iostream>

int main(){
  int value = 1;
  std::cout<<value <<std::endl;

  int value = 2;
  std::cout<<value <<std::endl;
  return 0;
}


However, why are we allowed to declare a variable inside of a loop? When the program goes through the loop multiple times it will continue to redeclare the same variable however there is no compiling error and it works just fine. For example in this code why is this allowed because we are redeclaring the variable newvalue each time when going through the loop?

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>

int main(){
  int value = 1;
  for(int i=0; i<5; ++i){
    int newvalue;  //newvalue is being redeclared 4 times.
    newvalue=value*2;
    value=newvalue;
    std::cout<<newvalue <<std::endl;
  }
  return 5;
}
Last edited on
It's a feature, not a bug. The variable gets constructed and destroyed each time through the loop. Sometimes this is quite useful, such as int newvalue{0} to initialize it to zero each time.

As you seem to understand, there's a downside to this behavior. If the variable is an instance of a class with a complicated constructor and/or destructor, then you might be needlessly creating & destroying it each time through the loop. Or maybe that's exactly the behavior you wanted, it all depends on the program and your intention.
@dhayden, thank you, so when we loop around for the second time, newvalue gets destroyed then recreated when entering the loop the second time, but what about value? that variable can't be destroyed yet because it is used to create newvalue when entering the loop. What happens to "value" and how does the compiler distinguish between what it does to value and newvalue?
The object named "value" is declared outside and before of the loop. It continues to exists to the end of the scope where it was declared.

We can "unroll" your loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>

int main(){
  int value = 1;
  {
    int i=0;
    {
      int newvalue;  // newvalue #1 is created
      newvalue = value*2;
      value = newvalue;
      std::cout << newvalue << std::endl;
      // newvalue #1 is destroyed
    }
    ++i;
    {
      int newvalue;  // newvalue #2 is created
      newvalue = value*2;
      value = newvalue;
      std::cout << newvalue << std::endl;
      // newvalue #2 is destroyed
    }
    ++i;
    {
      int newvalue;  // newvalue #3 is created
      newvalue = value*2;
      value = newvalue;
      std::cout << newvalue << std::endl;
      // newvalue #3 is destroyed
    }
    ++i;
    {
      int newvalue;  // newvalue #4 is created
      newvalue = value*2;
      value = newvalue;
      std::cout << newvalue << std::endl;
      // newvalue #4 is destroyed
    }
    ++i;
    // i is destroyed
  }
  return 5;
  // value is destroyed
}
It's called scope. Wherever you see {} it's introducing a new scope.

The value variable is declared inside the function's scope (line 4-11) so it will be accessible for the rest of the function. It will be created each time the function is called and destroyed when the function ends.

The newvalue variable is declared inside the loop's scope (line 6-9) so it is accessible for the rest of the loop. It will be created on each loop iteration and destroyed when the loop iteration ends.

http://en.cppreference.com/w/cpp/language/scope
Last edited on
@keskiverto, @Peter87, thank you, I fully understand it now.
Topic archived. No new replies allowed.