[comp.sys.amiga.programmer] SAS Bugs

T32QC@CUNYVM.BITNET (NEO) (01/28/91)

     Has anyone encountered any bugs in 5.10 with float math calculations in a
function and trying to pass the return values either with a global variable or
a typedef struct of floating point values. Then passing the values to the main
values dont truly get passed. I compile the progs same on a friends machine in
5.04 and it works fine. I am sick of writing code and seeing it is wrong on my
machine and its not my fault. I need help.
                                                 Thankyou,
                                                NEO  T32QC@CUNYVM

cunniff@hpfcso.HP.COM (Ross Cunniff) (01/29/91)

>     Has anyone encountered any bugs in 5.10 with float math calculations in a
>function and trying to pass the return values either with a global variable or
>a typedef struct of floating point values. Then passing the values to the main
>values dont truly get passed. I compile the progs same on a friends machine in
>5.04 and it works fine. I am sick of writing code and seeing it is wrong on my
>machine and its not my fault. I need help.

Well, this weekend, I just got bitten by the following nasty bug (this is
cut down from a much larger example, so no comments on programming style,
please).  The function:

	func( a, b )
	float a;
	long *b;
	{
	    *(float *)b = a;
	}

generated the code (this is from memory, and probably the wrong syntax as
well; that's what I get for using the HP assembler so much...)

	link.l	%a6,#0000
	mov.l	#000C(%a6),%a0			; Note this line; should
						; be #0010(%a6)
	movm.l	#0008(%a6),%d0-%d1
	jsr.l	convert_single_to_double	; don't remember the exact name
	mov.l	%d0,(%a0)
	unlk	%a6
	rts

It looks like the compiler realizes that it is actually a double on the
stack (hence the convert_single_to_double (or whatever nasty mnemonic they
use) call), but for the purposes of argument addressing, it thinks that
the size of the argument on the stack is *4* (not 8) bytes.  The workaround
is to rewrite the function as:

	func( a, b )
	double a;	/* Used to be float a */
	long *b;
	{
	    *(float *)b = a;
	}

Additionally, my application no longer works at all when compiled to
use the FFP math routines.  I haven't had time to track this down yet
(I have over 35k lines to search :-(), but when I do, I'll call SAS
and discuss it with them...

				Ross Cunniff
				Hewlett-Packard Colorado Language Lab
				cunniff@hpfcla.HP.COM

cunniff@hpfcso.HP.COM (Ross Cunniff) (02/05/91)

>>Well, this weekend, I just got bitten by the following nasty bug ...

>>	func( a, b )
>>	float a;
>>	long *b;
>>	{
>>	    *(float *)b = a;
>>	}
>>
>> [ explains how compiler thinks a is the size of a double ]

> This is NOT a bug.  This is how C used to work.  It bit me once
> several years ago.  Before the ANSI changes to C the only way to pass
> floating point numbers to a routine was as a double (never as a
> float).  Since you are using the old syntax then when you declare "a"
> as a float the compiler will "assume" it is a double since C used to
> only pass things as doubles.  The old syntax is kept for backward
> compatibility.

It most certainly IS a bug; you didn't read the assembly code.
The compiler thought the location of a was 4 bytes past the location
of b, not 8 as it should have been.  The code is old, so there was
no prototype present anywhere.  And yes, I already know how to work
around it.

By the way, I have already received a reply from a representative
of SAS who has provided me with some great support.  I have no
complaints with the company; all compilers have bugs, even the
ones I write...

				Ross Cunniff
				Hewlett-Packard Colorado Language Lab
				cunniff@hpfcla.HP.COM