[comp.lang.c++] Declare at first use?

jas@llama.Ingres.COM (Jim Shankland) (08/18/90)

In article <56642@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes:
>In article <1990Aug13.182226.24141@alias.uucp> bmcphers@alias.UUCP (Brent McPherson) writes:
>>Finally, common sense should prevail. If a variable is first assigned a value
>>within a loop it should be declared outside the loop just in case the compiler
>>decides to create the variable on the stack for each loop iteration.

>Hm, I'm not sure I understand what you're trying to say here.  In the 
>following code:
>
>	for (int i=0; i<1000; ++i)
>	{
>		FOO foo(i);
>		foo.DoSomething();
>	}

>It is certainly not the case that a thousand foos reside simultaneously
>on the stack.

Yes, but if you don't want foo's constructor and destructor to be called
on each loop iteration, you probably want to declare foo outside the loop,
even if it only gets used inside the body of the loop.

(Even in C, it's technically incorrect to declare an auto variable inside
a loop body, and expect its value to persist across loop iterations.
In practice, you get away with it -- at least I've never seen a system
where you don't -- because the compiler would have to go out of its
way to trash the value between iterations.)

jas

marc@dumbcat.sf.ca.us (Marco S Hyman) (08/19/90)

jimad> = jimad@microsoft.UUCP (Jim ADCOCK)
	 article <56642@microsoft.UUCP>

jimad> Hm, I'm not sure I understand what you're trying to say here.  In the 
jimad> following code:
jimad>
jimad>	for (int i=0; i<1000; ++i)
jimad>	{
jimad>		FOO foo(i);
jimad>		foo.DoSomething();
jimad>	}

jimad> It is certainly not the case that a thousand foos reside simultaneously
jimad> on the stack.

jas> = jas@llama.Ingres.COM (Jim Shankland)
       article <1990Aug17.191939.3990@ingres.Ingres.COM>

jas> Yes, but if you don't want foo's constructor and destructor to be
jas> called on each loop iteration, you probably want to declare foo outside
jas> the loop, even if it only gets used inside the body of the loop.

In the example given by jimad you *do* want foo's constructor and destructor
called every loop iteration.  I am assuming that the object created by the
constructor foo(0) is not the same as the object created by the constructor
foo(999).

jas> (Even in C, it's technically incorrect to declare an auto variable
jas> inside a loop body, and expect its value to persist across loop
jas> iterations. In practice, you get away with it -- at least I've never
jas> seen a system where you don't -- because the compiler would have to go
jas> out of its way to trash the value between iterations.)

But I don't the foo object to persist accross iterations.  I expect the
object to be destructed some time after it goes out of scope.  

C++ 2.0 (cfront, at least) does the right thing (with this simple example).
The program:

	class FOO {
	  public:
	    FOO(int i) : val(i) {};
	    ~FOO() {};
	    void DoSomething() {};
	  private:
	    int val;
	};

	int
	main()
	{
	    for (int i=0; i<1000; ++i) {
		FOO foo(i);
		foo.DoSomething();
	    }
	    return 0;
	}

Generates C code that looks something like:

	int main ()
	{
	    int i ;

	    for (i = 0; i < 1000; ++i ) { 
		struct FOO foo ;

		foo->val = i;
		; /* empty DoSomething */
	    }

	    return (int )0 ;
	}

Just as one might expect.

// marc
-- 
// marc@dumbcat.sf.ca.us
// {ames,decwrl,sun}!pacbell!dumbcat!marc

jimad@microsoft.UUCP (Jim ADCOCK) (08/21/90)

In article <1990Aug17.191939.3990@ingres.Ingres.COM> jas@llama.Ingres.COM (Jim Shankland) writes:
|In article <56642@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes:
|>Hm, I'm not sure I understand what you're trying to say here.  In the 
|>following code:
|>
|>	for (int i=0; i<1000; ++i)
|>	{
|>		FOO foo(i);
|>		foo.DoSomething();
|>	}
|
|>It is certainly not the case that a thousand foos reside simultaneously
|>on the stack.
|
|Yes, but if you don't want foo's constructor and destructor to be called
|on each loop iteration, you probably want to declare foo outside the loop,
|even if it only gets used inside the body of the loop.

Yes, I agree.  My understanding is that foo can be used for the side-effects
of its constructor and destructor, so that the compiler does not even have
the option of moving foo outside the loop.  If you don't want 1000s of
construction/destructions, move foo outside the loop.