[comp.sys.mac.programmer] Known Symantec Think C 4.01 bug and work-around

mitchell@tci.UUCP (Rob Mitchell) (10/23/90)

Subj:	Known Symantec Think C 4.01 bug and work-around
Date:	22-Oct-1990
Auth:	Rob Mitchell, Technology Concepts Inc.


BUG:	LLastClick, of List Manager routines, returns a long instead
	of a Cell type as defined in Inside Mac.

BUGGY CODE:
	...
	Cell		theCell;
	ListHandle	myList;

			/* compiler generates illegal 
			 * union/struct operation
			 */
	theCell = LLastClick (myList);
	...

SOLUTION:  Stick return of LLastClick into a long and cast 
	   long to Cell type.

SOLUTION CODE:
	...
	Cell		theCell;
	ListHandle	myList;
	long		tLong;

	tLong = LLastClick (myList);
	theCell = *(Cell *) &tLong;
	...

IN CLOSING:

	Symantec's Technial Support staff took all of 30 seconds to
analayze the problem and offer the solution.  I'm really impressed
by the service and quality of Symantec.  

steve@huxley.huxley.bitstream.com (Steve Stein) (10/23/90)

In article <514@tci.UUCP> mitchell@tci.UUCP (Rob Mitchell) writes:

>   Subj:	Known Symantec Think C 4.01 bug and work-around
>   BUG:	LLastClick, of List Manager routines, returns a long instead
>	   of a Cell type as defined in Inside Mac.
>
>   BUGGY CODE:
>	   ...
	   Cell		theCell;
>	   ListHandle	myList;
>
>			   /* compiler generates illegal 
>			    * union/struct operation
>			    */
>	   theCell = LLastClick (myList);
>

In all fairness to Symantec, THIS IS NOT A BUG!!! (This is a "feature" of C.)
C functions may not return structs (ref: Kernighan & Ritchie's "The C 
Programming Language", Appendix A ("C Reference Manual") Section 8.4: 
"functions may not return arrays, structures, unions or functions".)

The problem arises from the fact that the Mac Toolbox is designed with
Pascal interfaces (which may not exactly be the case nowadays).  Pascal
functions may return records ("struct"s in C).  Luckily for C, this
"record" (Cell) is only 4 bytes long, so C can return it in a register.
It's just that the C language won't allow declaring LLastClick as returning
the struct type Cell. 

The C language requires that LLastClick be declared as returning a long.

>   SOLUTION:  Stick return of LLastClick into a long and cast 
>	      long to Cell type.
>
>   SOLUTION CODE:
>	   ...
>	   Cell		theCell;
>	   ListHandle	myList;
>	   long		tLong;
>
>	   tLong = LLastClick (myList);
>	   theCell = *(Cell *) &tLong;


I find it more convenient to use:
           union cell_return_type {
               Cell c;
               long n;
           } theCell;
           ListHandle myList;

           theCell.n = LLastClick(myList);
and use "theCell.c" whenever I have to refer to the Cell's values.
This is a bit kludgy, but it generates better code.

>   IN CLOSING:
>
>	   Symantec's Technial Support staff took all of 30 seconds to
>   analayze the problem and offer the solution.  I'm really impressed
>   by the service and quality of Symantec.  

Hear, Hear!!!!!
Technical support for the THINK languages has long been a true
strength of THINK C and THINK Pascal.

Disclaimer: I used to work for THINK and Symantec.

- Steve Stein

lim@iris.ucdavis.edu (Lloyd Lim) (10/24/90)

In article <STEVE.90Oct23100517@huxley.huxley.bitstream.com> steve@huxley.huxley.bitstream.com (Steve Stein) writes:
>C functions may not return structs (ref: Kernighan & Ritchie's "The C 
>Programming Language", Appendix A ("C Reference Manual") Section 8.4: 
>"functions may not return arrays, structures, unions or functions".)

Your K&R is out of date.  This has changed with ANSI C.  Here's a quote from
K&R, Second Edition, p. 129, "The only legal operations on a structure are
copying it or assigning to it as a unit, taking its address with &, and
accessing its members.  Copy and assignment include passing arguments to
functions and returning values from functions as well."

To reiterate, in Appendix C, Summary of Changes, p. 260, "Structures may be
assigned, passed to functions, and returned by functions."

If you look at K&R 2 and the THINK C manual, you'll notice there are quite a
few differences between ANSI C and THINK C.

+++
Lloyd Lim     Internet: lim@iris.ucdavis.edu (128.120.57.20)
              Compuserve: 72647,660
              US Mail: 215 Lysle Leach Hall, U.C. Davis, Davis, CA 95616

steve@huxley.huxley.bitstream.com (Steve Stein) (10/24/90)

In article <7865@ucdavis.ucdavis.edu> lim@iris.ucdavis.edu (Lloyd Lim) writes:
>In article <STEVE.90Oct23100517@huxley.huxley.bitstream.com> 
>steve@huxley.huxley.bitstream.com (Steve Stein) writes:
>>C functions may not return structs (ref: Kernighan & Ritchie's "The C 
>>Programming Language", Appendix A ("C Reference Manual") Section 8.4: 
>>"functions may not return arrays, structures, unions or functions".)
>
>Your K&R is out of date.  This has changed with ANSI C.  Here's a quote from
>K&R, Second Edition, p. 129, "The only legal operations on a structure are
>copying it or assigning to it as a unit, taking its address with &, and
>accessing its members.  Copy and assignment include passing arguments to
>functions and returning values from functions as well."
>
>To reiterate, in Appendix C, Summary of Changes, p. 260, "Structures may be
>assigned, passed to functions, and returned by functions."
>

ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
ANSI C allows functions to return a struct.
...

Thanks Lloyd, and to those who wrote to update my knowledge of C.
(I would reply by eMail, but my eMail is bouncing.)

- Steve Stein

siegel@endor.uucp (Rich Siegel) (10/25/90)

In article <STEVE.90Oct23100517@huxley.huxley.bitstream.com> steve@huxley.huxley.bitstream.com (Steve Stein) writes:
>In article <514@tci.UUCP> mitchell@tci.UUCP (Rob Mitchell) writes:
>
>>   Subj:	Known Symantec Think C 4.01 bug and work-around
>>   BUG:	LLastClick, of List Manager routines, returns a long instead
>>	   of a Cell type as defined in Inside Mac.

	This is not a bug. The reason that LLastClick returns a long is because
functions declared 'pascal' (such as all of the Toolbox routines) in THINK C
may not return structures or any simple type larger than 4 bytes (such as
a result-type of 'double'). The behavior of 'pascal'-declared functions is
not standardized, and is pretty much implementation-dependent. (A future
release of THINK C may support the returning of structured function results
by 'pascal' functions.

One way to deal with LLastClick is to cast the result using a pointer cast;
the compiler will recognize this trick for what it is and generate a simple
move. If you feel more comfortable doing it explicitly, you can try this:

{
	extern LLastClick();

	asm {
		clr.l	-(a7)		; function result
		move.l	myList, -(a7)	; argument
		jsr	LLastClick	; call it
		move.l	(a7)+, theCell	; pop result
	}
}

R.



 Rich Siegel	Software Engineer	Symantec Languages Group
 Internet: siegel@endor.harvard.edu	UUCP: ..harvard!endor!siegel

If you have telekinetic powers, raise my hand.

phils@chaos.cs.brandeis.edu (Phil Shapiro) (10/25/90)

Not to knock a compliment, but the 'bug' in LLastClick() is described
on p. 122 of the User's Manual.  Perhaps an easier workaround to this
problem would be:

main()
{
    Cell c;
    ListHandle list;

    *(long *)&c =  LLastClick(list);
}

	-phil
--
   Phil Shapiro                           Technical Support Analyst
   Language Products Group                     Symantec Corporation
		Internet: phils@chaos.cs.brandeis.edu

willcox@urbana.mcd.mot.com (David A Willcox) (10/25/90)

In article <STEVE.90Oct23100517@huxley.huxley.bitstream.com> steve@huxley.huxley.bitstream.com (Steve Stein) writes:

>In all fairness to Symantec, THIS IS NOT A BUG!!! (This is a "feature" of C.)
>C functions may not return structs (ref: Kernighan & Ritchie's "The C 
>Programming Language", Appendix A ("C Reference Manual") Section 8.4: 
>"functions may not return arrays, structures, unions or functions".)

In all fairness to C, your statement is false.  C functions have been
able to return structures for quite some time - I think that every
UNIX compiler I've used since Version 6 days has allowed it.  You're
right, K&R does say that it is illegal, but it is a very common
extension to allow it.

Also, to quote the ANSI C standard (subclause 3.7.1):

    The return type of a function shall be void or an object type
    other than array.

In other words, in ANSI C, returning a structure definitely IS legal.