hzyfr's blog

By hzyfr, 10 years ago, In English

As it knowns to all c++ coders, re-defining loop variable is a undefined behavior that leads to a unexpected result of your program, or sometimes Runtime error.

This often happens when you want to write a long loop statement:


for(int i = 0; i <= n; ++i) { //do something very complicated for(int i = 0; i <= m; ++i) { ...... } }

Usually after you use the outer loop variable i to do something, the variable i become useless, but you want to do other works inside the loop , and you forget that you have defined i outside.

Then when you run your program you will find something strange happens. Maybe the program never stops or the program enters the first loop and only run one time then stops. I think most of the coders have such experience. Also this bug is not easy to discover(though fixing it is really simple work).

However this error can easily be detected by compilers, if it check every definitions inside a loop that defines temporary loop variable(s). I would say that if the compiler does that work and give us a warning then it will not be a disgusted, hard-to-find bug anymore. So I really hope the compilers will support such a feature in the near future.

  • Vote: I like it
  • +14
  • Vote: I do not like it

»
10 years ago, # |
  Vote: I like it +16 Vote: I do not like it

em, AFAIK it's perfectly valid and visible variable is just one in inner loop

  • »
    »
    10 years ago, # ^ |
    Rev. 2   Vote: I like it +11 Vote: I do not like it

    Yes, I think that this is not undefined behavior. Consequences of this bug (such as array index overflow) can have undefined behavior, but not shadowing itself.

    Moreover, there are situations, when shadowing is very useful. But I personally prefer to avoid it everywhere.

»
10 years ago, # |
Rev. 2   Vote: I like it +16 Vote: I do not like it
➜  test git:(master) ✗ cat a.cpp
#include <iostream>
#include <cmath>
typedef long long li;
using namespace std;

int main() {
	cout.precision(20);
	for(int i = 0; i < 5; ++i){
		for(int i = 0; i < 2; ++i) {
			cout << i;
		}
	}
}
➜  test git:(master) ✗ g++ a.cpp -Wshadow
a.cpp: In function ‘int main()’:
a.cpp:9:11: warning: declaration of ‘i’ shadows a previous local [-Wshadow]
   for(int i = 0; i < 2; ++i) {
           ^
a.cpp:8:10: warning: shadowed declaration is here [-Wshadow]
  for(int i = 0; i < 5; ++i){
          ^
➜  test git:(master) ✗ 

-Werror may be also interesting to you

  • »
    »
    10 years ago, # ^ |
      Vote: I like it +8 Vote: I do not like it

    Thank you ! Maybe I don't set the compiler on my computer. I will add -Wall command while compiling.

    • »
      »
      »
      10 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Unfortunately, -Wall don't include -Wshadow