[comp.sys.mac.programmer] LSC 3.0 Boolean Bug/Feature

oster@dewey.soe.berkeley.edu (David Phillip Oster) (08/05/88)

LightSpeed C 3.0 compiles a slightly different language than the older
LightSpeed Cs, and it can get you into trouble. You will have no trouble
if you religiously use protypes. Use prototypes.

Under the lightspeed C, the following program will always print "False":
----- file 1 ------
#include <stdio.h>
main(){
	if(Oster()){
		printf("True");
	}else{
		printf("False");
	}
}
----- file 2 -----
#include <MacTypes.h>
Boolean Oster(){ return FALSE; }
-------------------

Under LightSpeed C version 3.0, this program will print "True", but only
some of the time!

You see, in file 1, the function Oster() wasn't explicitly declared, so
its declaration defaults to int Oster();  But Oster() is really of type
Boolean, which is a small enum, in paticular, an enum small enough to fit
in a char.  

Under the old C, this still worked, because char function
returns were sign extended to int. Under the new C, Oster() returns a
char, but main expects to see an int, and nobody is clearing the high byte
of the return value.  That high byte is whatever happened to be in the
function return register. Sometimes its zero, sometimes its not. If it
happens to be zero, main will print "False". Otherwise, main will print
"True".

In article <586@mailrus.cc.umich.edu> shane@um.cc.umich.edu (Shane Looker) writes:
>I would strongly advise using prototypes.  They are very handy, since they
>can not only save you on problems like this, but they allow the compiler to
>know what you want to pass, not second guess you.
>
>Shane Looker
>Looker@um.cc.umich.edu

I couldn't say it more eloquently.

--- David Phillip Oster            --When you asked me to live in sin with you
Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth.
Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu

oster@dewey.soe.berkeley.edu (David Phillip Oster) (08/07/88)

In article <25467@ucbvax.BERKELEY.EDU> I write:
>LightSpeed C 3.0 compiles a slightly different language than the older
>LightSpeed Cs, and it can get you into trouble. You will have no trouble
>----- file 2 -----
>#include <MacTypes.h>
>Boolean Oster(){ return FALSE; }
>-------------------

correction. The above Oster() function actually clears all of the function
return register.  To see the bug, use the following file2:

----- file 2 -----
#include <MacTypes.h>	/*actually redundant, this line included for clarity*/
Boolean Oster(){
	Boolean data[2];

	data[0] = FALSE;
	return data[0];
}
---------------------

If you single step through the program, you'll watch LSC move the result
of Oster into D0 with a MOVE.B instruction, return, and then test the
result with a TST.W instruction. If you seed D0 with garbage before the
call to Oster(), the program will print "True" even though "False" was
returned.

I don't think LSC is broken, I justthink there is somethinbg in the
proposed ANSI standard that mandates this unfortunate behavior.

--- David Phillip Oster            --When you asked me to live in sin with you
Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth.
Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu