[comp.lang.c] Initialization of automatics within loops

geoff@locus.com (Geoff Kuenning) (02/05/91)

The following little program demonstrates a problem found in the XSend()
routine of XlibInt.c:

	main ()
	    {
	    int i = 0;
	    while (i < 3)
		{
		int j = 4;
		printf ("i = %d, j = %d\n", i, j);
		i++;
		j++;
		}
	    }

What does this print?  On the machine I'm using, it prints the same value
for j (j = 4) three times.  On the other hand, the programmer of XSend()
clearly expected three different values for j.

I just checked the ANSI C spec on this, and found it unclear.  It is
explicitly stated that automatics are initialized on every entry to a
compound statement.  However, it is not made clear whether the construct:

	while (<expression>)
	    <statement>

is considered to *re-enter* the compound statement every time or not.  My
instinct says yes, the statement is re-entered, but obviously this
interpretation is open to discussion.  In terms of usefulness, I could
argue that either option is useful to programmers.

What do people think the spec should do about this question?  (BTW, the
spec explicitly says that implementations get to decide whether automatics
are initialized upon jumps into a compound statement, so perhaps this
issue should also be implementation-defined).

I'm cross-posting to comp.windows.x so that X-Windows users will be made
aware of a potential bug (the problem will show up only under certain
very rare conditions, so it could be lurking in your system without your
knowledge).
-- 

	Geoff Kuenning	geoff@la.locus.com	geoff@ITcorp.com

gwyn@smoke.brl.mil (Doug Gwyn) (02/06/91)

In article <1991Feb5.023809.389086@locus.com> geoff@locus.com (Geoff Kuenning) writes:
-	    while (i < 3)
-		{
-		int j = 4;
-		printf ("i = %d, j = %d\n", i, j);
-		i++;
-		j++;
-		}
-What does this print?  On the machine I'm using, it prints the same value
-for j (j = 4) three times.  On the other hand, the programmer of XSend()
-clearly expected three different values for j.

The programmer clearly made a mistake.  j has the value 4 for each
execution of the printf().  I was unable to tell from the code
snippet just what the programmer intended; merely changing the
storage class of j to "static" would probably not be correct either.

-I just checked the ANSI C spec on this, and found it unclear.  It is
-explicitly stated that automatics are initialized on every entry to a
-compound statement.  However, it is not made clear whether the construct:
-	while (<expression>)
-	    <statement>
-is considered to *re-enter* the compound statement every time or not.

There is no question whatsoever about this.  The compound statement is
completely evaluated for each iteration; this includes the auto
initialization.

tom@flood.com (Tom Chatt) (02/12/91)

In article <1991Feb5.023809.389086@locus.com> geoff@locus.com (Geoff Kuenning) writes (paraphrases in brackets):
> [ In the following example (drawn from actual Xlib code): ]
>
>	main ()
>	    {
>	    int i = 0;
>	    while (i < 3)
>		{
>		int j = 4;
>		printf ("i = %d, j = %d\n", i, j);
>		i++;
>		j++;
>		}
>	    }
>
> [ Does the initialization of j=4 occur at the start of each iteration
>   of the compound statement, or only the first iteration? Mr. Kuenning's
>   compiler sets j=4 each time; the X programmer evidently expected otherwise.
>   The ANSI C standard says that automatics are initialized on every entry
>   to a compound statement, but does the above example count as three
>   entries to the compound statement, or only one? ]

WRT entering the compound statement, it seems pretty clear to me that
the compound statement is re-entered at each iteration, and that the
initialization (as per spec) should occur each time. I say this because
the test "i < 3" is clearly outside of the compound statement, and this
executes at each iteration, thus you must have exited the compound statement.

Though a compiler *may* optimize this out, it would be perfectly
correct for a compiler to *allocate* the automatic variable at each
entry to the compound statement. In the example above, the programmer
has some expectation about the value of the automatic variable persisting
outside of its scope (i.e., between iterations). This practice is
extremely dubious and inadvisable. If a programmer expects a variable's
value to persist outside of its scope, he should declare it as static.
-- 
Tom Chatt                        \   Don't take offense, take action.
Internet: tom@flood.com           \    Speak up. When we remain silent,
UUCP: ...!uunet!flood!tom        / \     we oppress ourselves.