[comp.sys.mac.misc] Possible Think C bug

ted@cs.utexas.edu (Ted Woodward) (04/23/91)

OK, I don't think I'm crying wolf this time :-)

X2Fix doesn't work.  According to IM IV, X2Fix takes an extended and converts
it to a Fixed.  Well, according to the Think C manual, Fix2X converts a Fixed
to a double, not extended.  No mention is made of X2Fix.  But the compiler
barfs if I pass it anything but a float; "pascal argument wrong size".  And
then the toolbox routine thinks it is getting an extended, so it returns the
wrong answer.  For example, X2Fix of 1.0 returns 0, not 0x00010000.

And unfortunately, X2Fix is not declared in one of the header files like Fix2X
is; I assume it's in macheaders, which we can't modify.

FYI, I'm using Think C v4.1.


-- 
Ted Woodward (ted@cs.utexas.edu)

"Mad scientists HATE shopping for shoes!" -- Peaches

siegel@world.std.com (Rich Siegel) (04/23/91)

In article <1355@lovelady.cs.utexas.edu> ted@cs.utexas.edu (Ted Woodward) writes:
>OK, I don't think I'm crying wolf this time :-)
>
>X2Fix doesn't work.  According to IM IV, X2Fix takes an extended and converts
>it to a Fixed.  Well, according to the Think C manual, Fix2X converts a Fixed
>to a double, not extended.  No mention is made of X2Fix.  But the compiler
>barfs if I pass it anything but a float; "pascal argument wrong size".  And
>then the toolbox routine thinks it is getting an extended, so it returns the
>wrong answer.  For example, X2Fix of 1.0 returns 0, not 0x00010000.
>

In THINK C, the C 'double' is the same as the SANE/Pascal 'Extended'. This
is described on page 117 of the 4.0 user's manual, in "Floating point 
arithmetic".

X2Fix is declared in the built-in traplist, not in any header files; this
is because X2Fix returns an integral data type, so no prototype is necessary
to redeclare it, as is the case for LNew (for example).

The declaration (in Pascal) for X2Fix is

	function X2Fix(x : Extended) : Fixed;

Since X2Fix is, like all of the Mac traps, a 'pascal' function, it can neither
return a result nor accept an argument which is larger than four bytes. In
Pascal this holds true as well, but the details are taken care of internally
by the compiler. In C, the prototype for X2Fix would be something like:

	pascal Fixed X2Fix(double *x);

Note that for 'pascal' functions, any argument larger than four bytes is
passed by address, thus the necessity to pass the *address* of a double.

The following code fragment illustrates this, and works correctly:

main()
{
	Fixed f;
	double d = 1.0;
	
	f = X2Fix(&d);
}

'f' ends up with the value 65536, or 0x00010000.

>And unfortunately, X2Fix is not declared in one of the header files like Fix2X
>is; I assume it's in macheaders, which we can't modify.

MacHeaders is a precompiled header generated from the "Mac #includes.c" file,
which is supplied in the package. By modifying any of the include files
specified in Mac #includes.c and re-precompiling it, you can generate a 
modified MacHeaders. This is described on page 118 of the current user's
manual, in "Editing the MacHeaders file".


R.
-- 
-----------------------------------------------------------------------
Rich Siegel                              Internet: siegel@world.std.com
Software Engineer                        Applelink: SIEGEL
Symantec Languages Group