for != while

Vax Operators operator at pogo.UUCP
Fri Sep 5 02:20:40 AEST 1986


In article <570 at copper.UUCP> mikeb at copper.UUCP (Mike Beckerman) writes:
>In article <15525 at ucbvax.BERKELEY.EDU> ballou at brahms.UUCP (Kenneth R. Ballou) writes:
>>In article <86900030 at haddock> karl at haddock writes:
>>>
>>>main() {
>>>	char *foo = "outer";
>>>	for (;; printf(foo),exit(0)) {
>>>		char *foo = "inner";
>>>	}
>>>}
>>>
>>>This prints "outer" (vax SVR2 compiler), though the for-while equivalence
>>>might lead one to expect "inner".
>>
>>I don't think the issue here is equivalence of for and while statements.
>>The point is that the scope of the inner 'foo' is the compound statement
                                                        ^^^^^^^^

>>which is the body of the for statement.  So, quite rightly, the 'foo'
>>given as the argument to printf in the third expression of the for statement
>>refers to the most closely nested declaration of 'foo' -- the body of the
>>for statement is one block level higher and is not visible at this point.
                       ^^^^^^^^^^^^^^^^^^
>
>That was my first thought as well, but both K&R and the proposed ANSI C standard
>define the "for" loop as follows:
>
>	for (expression-1 ; expression-2 ; expression-3) statement
>
>		is equivalent to
>
>	expression-1;
>	while (expression-2) {
>		statement
>		expression-3;
>	}
>
>which to me says that the example should have printed "inner".


I think the mistake being made here is a confusion with scope.  Yes,
that's the definition of while and for, but look carefully at the
definition for 'while':  it has { statement } (brackets surrounding
the statement) after the conditional, while the for has no brackets.
Therefore, the correct translation of your for loop into a while loop
is as follows:

main() {
	char *foo = "outer";
	while (TRUE)
	{
		{
			char *foo = "inner";
		}
		printf(foo);
		exit(0)
	}
}

The for loop execution order is  /* for (exp1; exp2; exp3) statement; */

		exp1;		<=>	    ;
		exp2;		<=>	    ;
		statement;	<=>	{ char *foo = "inner" }
		exp3;		<=>	printf(foo); exit(0);


The 'char *foo = "inner"' disappears when the deeper scope gets popped,
therefore the foo that gets printed is still "outer".

Shannon Nelson
"Where there is a will, there's lot's of relatives...'



More information about the Comp.lang.c mailing list