[net.lang.c] Optimization error?

joey@reed.UUCP (Joe Pruett) (04/18/86)

We recently discovered an interesting gotcha in the Apollo
C compiler.  We had code similar to this:

func(x)
int x;
{
	int flag;

	if (x < 0) {
		printf("Bad news\n");
	} else {
		flag = 1;
	}

	do {
		printf("Hello, world.\n");
	} while (!flag);
}

Yes, there is an error in that flag may not get set before it
is used.  I was horrified to find out that lint won't catch
this kind of an error.  Anyway, the interesting part is that
the compiler determined that the expression !flag would always
be 0, and therefore optimized it away causing the do-while loop
to exit after one pass.

I contend that if the compiler could figure out that flag could
get set to 1, then it should also figure out that flag might not
bet set to anything, and at least issue a warning, but it should
not optimize the expression away.

Is this a bug, or a misfeature, or an inherent gotcha with fancy
optimization?
-- 
	Joe Pruett
	Test Systems Strategies, Inc.
	...!tektronix!reed!tessi!joey

greg@utcsri.UUCP (Gregory Smith) (04/21/86)

In article <3109@reed.UUCP> joey@reed.UUCP (Joe Pruett) writes:
>I contend that if the compiler could figure out that flag could
>get set to 1, then it should also figure out that flag might not
>bet set to anything, and at least issue a warning, but it should
>not optimize the expression away.
>
>Is this a bug, or a misfeature, or an inherent gotcha with fancy
>optimization?

I would say that a run-time bug in your code has propogated its way
into compile-time - an inherent gotcha.  To determine in general that
the flag may not be set is probably (?) similar to the halting problem
- it can't be done (* In General *) so it will only be detected for
simple cases. Lint apparently looks at the textual order of operations
 - the following draws a warning:

	int i,j;
	for(i=1;i<=2;++i){
		if(i==2) printf("j = %d\n", j );
		j = 123;
	}

Lint will say that j is used before it is set. An example can be set up
with goto's { goto b; a: use(j); return; b: j=0; goto a;}. In this
case it is more obvious that the code is ok but Lint will still warn.
-- 
"If you aren't making any mistakes, you aren't doing anything".
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg