QuickC

Chris Torek chris at mimsy.UUCP
Sat Aug 27 05:27:34 AEST 1988


In article <8808261424.AA11504 at ucbvax.Berkeley.EDU> TURGUT at TREARN.BITNET
(Turgut Kalfaoglu) noticed some wrong code that worked anyway:

>square(num) int num; { num = num*num; }

>... There is no 'return' statement in the function. However, it works!
>... I thought maybe it was keeping the result of the last operation,
>so I added some dummy lines,

>square(num) int num; { int dummy; num = num*num; dummy=222; }

>but the call STILL works... WHY does it work?

Luck.

More seriously: it is due to a combination of the compiler and the
machine architecture.  The compiler does a multiply by loading the
multiplicand and multiplier (in this case, num and num) into one or
more registers (here, one suffices), multiplying the registers, and
perhaps storing the result (the store may well be deleted by a
dead-store checker).  For whatever reason, it chooses the same register
that the compiler/architecture uses for integer return values.
The dummy assignment is either eliminated completely by a dead-store
checker, or else is done by a memory-to-memory or immediate-to-memory
move, which does not overwrite that register.  Then, since there is no
return statement at all, nothing is put into the return-value register,
leaving the old num*num result.

A more common occurrence of this same bug appears as follows:

	/* caller: */
		var = fn(args);
		...

	int fn(args) { ...; otherfn(otherargs); }

	int otherfn(args) { ...; return (expr); }

On architectures with a common return-value register---e.g., VAX (r0),
Intel 80*86 (ax), MC680X0 (d0)---this works.  Fortunately, lint catches
this sort of error, before you attempt to run the code on a Pyramid....
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list