Repeated Declarations

Hi all!

Just a curious question

I know that the first parameter of a for loop only happens once
e.g.
1
2
3
4
for ( int i = 0; i < 10; i++ )
{ 
    blah blah code
}


so that i is declared once

but what if i did this?

1
2
3
4
5
6
7
for ( int i = 0; i < 10; i++ )
{ 
    for ( int j = 0; j < 10; j++ )
    {
        blah
    }
}


will j be declared 10 times or some other random thing?

Just want your opinions and knowledge on if this is effective too, many thanks!
It looks the following way

1
2
3
4
5
6
7
8
9
10
11
int i = 0;
while ( i < 10 )
{
   int j = 0;
   while ( j < 10 )
   {
      blah;
      j++;
   }
   i++;
} 


So for each i < 10 the internal loop will be executed. Variable j will be created and destroyed 10 times inside the outer loop.
Last edited on
Try it for yourself. By writing a class around the int type, you can see the creation of the integer objects through their constructor calls.

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
#include <iostream>
using namespace std;

class Integer
{
public:
	Integer(int i) : value(i) { cout << "Constructor" << endl; }
	operator int() { return value; }
	Integer operator++(int) { value++;  return *this; }
private:
	int value;
};

int main()
{
	for (Integer i = 0; i < 10; i++)
	{
		for (Integer j = 0; j < 10; j++)
		{
			cout << "blah blah code. i = " << i
				<< "  j = " << j << endl;
		}
	}

	return 0;
}
The compiler will optimize things, though - the behavior with a class object will not always be the behavior with a primitive.
It's worth noting that creating or destroying an integer on the stack only involves incrementing or decrementing a pointer. And the compiler could in principle move this bit around, so that this:
1
2
3
4
5
6
7
for ( int i = 0; i < 10; i++ )
{ 
    for ( int j = 0; j < 10; j++ )
    {
        blah
    }
}
actually becomes this (ignoring lexical scope):
1
2
3
4
5
6
7
8
9
int i;
int j;
for ( i = 0; i < 10; i++ )
{ 
    for ( j = 0; j < 10; j++ )
    {
        blah
    }
}

Creating an object is potentially arbitrarily complex. For POD types, it should be as cheap as an integer. For more complex types, it may at least involve a function call.
Everything is subject to the "as if" rule. The observable behaviour of the program is 'as if' int j was created, initialized and trivially destroyed 10 times.

Here, "initialize j" will be printed 10 times:
1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    for( int i = ( (std::cout<<"initialize i\n"), 0 ) ; i < 10 ; ++i )
        for( int j = ( (std::cout<<"\tinitialize j\n"), 0 ) ; j < 10 ; ++j )
        {
            // whateverh
        }
} 


Here, i, j and k will be optimized away:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int foobar()
{
    int k = 0 ;
    for( int i = 0 ; i < 10 ; ++i )
        for( int j = 0 ; j < 10 ; ++j )
            ++k ;
    return k ;

    ////////  generated code /////////////
    //    __Z6foobarv:
    //         movl	$100, %eax
    //         ret
    //
    // equivalent to: return 100 ;
    //
    //////////////////////////////////////
}
Last edited on
Topic archived. No new replies allowed.