[comp.sys.mac.programmer] LSC almost gets it right.

rcb@rti.UUCP (Randy Buckland) (09/01/88)

Well, last night I found my first gripe with LSC 3.0. Before that I
was perfectly happy with the system. I still like it and I think this
problem could be fixed without a great deal of difficulty.

I was adding all the standard event handling code to a new program.
This is my first C program on the MAC I have written Pascal programs
on the MAC and C programs on other machines, so I didn't expect any problem.

My problem came with expecting the built-in prototypes for the MAC ROM
functions to prevent any mistakes in parameters passing. But apparently,
they only check the size of an argument and do not enforce strict type
compatability like normal prototypes do. Anyway I had the following lines
in my program:

	Point position;
		.
		.
	GLobalToLocal (position);

As is now obvious, position was not passed by reference, but by value.
Since the function wanted an address which is 4 bytes and the position
structure (2 integers) is 4 bytes, the compiler said ok and just pushed 
the structure onto the stack. Naturally, this caused all kinds of 
grief since position contained the current mouse position where the event
occured. THe function would merrily take that screen position as an address
and convert the value at that address from global coordinates to local
coordinates. SInce this was an almost totally random failure mode, it was 
impossible to track down. I eventually found it by checking the calling
sequence for every ROM call in my program.

I plan to try to define a real prototype for this function and see if it
still allows this kind of error. So Rich, how about an include file from
Think that defines real prototypes for all the ROM functions.
-- 
					Randy Buckland (919)-541-7103
					Research Triangle Institute
					rcb@rti.rti.org [128.109.139.2]
					{decvax,ihnp4}!mcnc!rti!rcb

shane@chianti.cc.umich.edu (Shane Looker) (09/02/88)

In article <2423@rti.UUCP> rcb@rti.UUCP (Randy Buckland) writes:
!My problem came with expecting the built-in prototypes for the MAC ROM
!functions to prevent any mistakes in parameters passing. But apparently,
!they only check the size of an argument and do not enforce strict type
!compatability like normal prototypes do. Anyway I had the following lines
!in my program:
!
!	Point position;
!	GLobalToLocal (position);
!
!I plan to try to define a real prototype for this function and see if it
!still allows this kind of error. So Rich, how about an include file from
!Think that defines real prototypes for all the ROM functions.
!-- 
!					Randy Buckland (919)-541-7103


The manual clearly states that the MacTraps calls do not have prototypes.
(User Manual: p. 124, 1st Paragraph.)

You can add prototypes with no problem.  (User Manual: p. 125, 3rd Paragraph.)

Shane Looker
Looker@um.cc.umich.edu

mce@tc.fluke.COM (Brian McElhinney) (09/07/88)

In article <670@mailrus.cc.umich.edu> shane@um.cc.umich.edu (Shane Looker) writes:
>The manual clearly states that the MacTraps calls do not have prototypes.
>
>You can add prototypes with no problem.

Documenting a bug does not make it a feature (the Require Prototypes option
should *require* prototypes for *all* routines; anything less is a bug).

Adding prototypes yourself would be time consuming and error prone, which is
very likely the reason that traps are not prototyped in the first place.  The
only other reason I can think of is that it could "break" some "working" code.
How many DisposHandle() calls are really correctly written?  Sure they work,
but they would never pass lint -- if there were such a thing as lint :-(.

Given the general quality of LSC, I am confident that trap prototypes will
eventually be added.  I have to admit to some disappointment though; same as
when I realized that lint was not provided.  Lint is not perfect, but it is a
useful tool.  In the immortal words of Henry Spencer:

	"Thou shall run lint consistently and study its pronouncements
	 with care, for verily its perception and judgement oft exceed
	 thine."



Brian McElhinney
mce@tc.fluke.com

ech@poseidon.UUCP (Edward C Horvath) (09/07/88)

From article <5077@fluke.COM>, by mce@tc.fluke.COM (Brian McElhinney):
> In article <670@mailrus.cc.umich.edu> shane@um.cc.umich.edu (Shane Looker) writes:
>>The manual clearly states that the MacTraps calls do not have prototypes.
>>
>>You can add prototypes with no problem.
 
> Documenting a bug does not make it a feature (the Require Prototypes option
> should *require* prototypes for *all* routines; anything less is a bug).
 
What drives me NUTS about LSC prototyping (at least in 2.x: my check for 3.0
cleared the bank three weeks ago, Symantec, where's my upgrade???) is the
SILENT coercion of (incorrect) arguments.  Example: you pass 0 for the space
parameter to NewWindow.  This is an error, folks, it needs to be NIL or NULL
or, in any case, a LONG zero.  LSC is happy to silently notice that
the value ought to be long, and indeed generates code to push a long zero.

Great.  Unless you have hopes of sharing your code with ANYBODY who doesn't
have LSC.  Now Symantec/Think may just snicker because this misfeature
makes it even easier to write code -- incorrect, but acceptable to LSC,
code -- and harder to port it to another compiler.  But it's MY code, and
I reserve the right to own more than one compiler.

I'd rather be warned about type mismatches, and I'd be happy to turn on a
"picky, picky, picky!" option if there were one.  Meantime it just makes
me paranoid...

=Ned=

kaufman@polya.Stanford.EDU (Marc T. Kaufman) (09/08/88)

In article <490@poseidon.UUCP> ech@poseidon.UUCP (Edward C Horvath) writes:
 
>What drives me NUTS about LSC prototyping... is the
>SILENT coercion of (incorrect) arguments.  Example: you pass 0 for the space
>parameter to NewWindow.  This is an error, folks, it needs to be NIL or NULL
>or, in any case, a LONG zero.  LSC is happy to silently notice that
>the value ought to be long, and indeed generates code to push a long zero.

Well, K&R says that '0' casts correctly to any NIL type.  If you were using
MPW, '0' would already be 32 bits.  Syntax correctness does not imply semantic
correctness.

Marc Kaufman (kaufman@polya.stanford.edu

conybear@bruce.oz (Roland Conybeare) (09/08/88)

From article <5077@fluke.COM>, by mce@tc.fluke.COM (Brian McElhinney):
> In article <670@mailrus.cc.umich.edu> shane@um.cc.umich.edu (Shane Looker) writes:
>>The manual clearly states that the MacTraps calls do not have prototypes.
>>
>>You can add prototypes with no problem.
> 
> Documenting a bug does not make it a feature (the Require Prototypes option
> should *require* prototypes for *all* routines; anything less is a bug).

	Ahem!  My version of LSC (2.01) when told to "require prototypes",
complains about all unprototyped calls, *including* toolbox traps.
	So while I would agree that not providing prototypes for toolbox traps
is an omission, I would not call it a bug.

	While I am firmly seated upon my hobby horse,  I wish (Oh, how I wish)
that LSC would allow me to prototype either types or declarations, e.g.
	typedef int (*COMPARE_FN)( float x, float y );
or
	typedef struct {
		int	(*compare_fn)( float x, float y );
		...
	} FOO;
or
	{
		int	(*compare_fn)( float x, float y );
	}

	At the moment, once you start using pointers to functions, you lose
all of that wonderful prototype checking.

Roland Conybeare
(conybear@moncsbruce.oz)

P.S. and yea verily, doth lint, in its wisdom, deign to check calls to
	functions, where such calls be made through pointers?

nagel@paris.ics.uci.edu (Mark Nagel) (09/08/88)

In article <3873@polya.Stanford.EDU> kaufman@polya.Stanford.EDU (Marc T. Kaufman) writes:
|In article <490@poseidon.UUCP> ech@poseidon.UUCP (Edward C Horvath) writes:
| 
|>What drives me NUTS about LSC prototyping... is the
|>SILENT coercion of (incorrect) arguments.  Example: you pass 0 for the space
|>parameter to NewWindow.  This is an error, folks, it needs to be NIL or NULL
|>or, in any case, a LONG zero.  LSC is happy to silently notice that
|>the value ought to be long, and indeed generates code to push a long zero.
|
|Well, K&R says that '0' casts correctly to any NIL type.  If you were using
|MPW, '0' would already be 32 bits.  Syntax correctness does not imply semantic
|correctness.

This is only true for pointer assignment in K&R, you still have to cast NULL
for function calls or anywhere else where the actual pointer type isn't
clear from context.  In fact, I think that prototype conversion is very
nice.  You don't have to worry about what you've cast your NULL to. 
Since the compiler has a prototype in scope, it knows what type the
NULL pointer should be because it has context always, just as in
assignnment.  I believe this was one of the big reasons for adding 
prototypes to C.  Now if Think would just add ANSI prototypes...

-- 
Mark Nagel
Department of Information and Computer Science, UC Irvine
nagel@ics.uci.edu             (ARPA)             When they ship styrofoam...
{sdcsvax|ucbvax}!ucivax!nagel (UUCP)             ...what do they pack it in?

ech@poseidon.UUCP (Edward C Horvath) (09/10/88)

Earlier I wrote
  
!What drives me NUTS about LSC prototyping... is the
!SILENT coercion of (incorrect) arguments.  Example: you pass 0 for the space
!parameter to NewWindow.  This is an error, folks, it needs to be NIL or NULL
!or, in any case, a LONG zero.  LSC is happy to silently notice that
!the value ought to be long, and indeed generates code to push a long zero.
 
From article <3873@polya.Stanford.EDU>, by kaufman@polya.Stanford.EDU (Marc T. Kaufman):
! Well, K&R says that '0' casts correctly to any NIL type.  If you were using
! MPW, '0' would already be 32 bits.  Syntax correctness does not imply semantic
! correctness.

That's right.  But a compiler that implements non-standard semantics, silently,
is no longer a C compiler.  An explicit cast a la K&R is fine by me, e.g.
	myPtr = 0;
As is the casting incorporated into C++: one can overload a method to accept
different types for the same positional parameter, and the cast then
becomes explicit in the overloaded method implementation.

But the only casting K&R, or anyone else to date, provide for function
arguments is to promote integer types smaller than int to int (NOT long!)
and to promote floating point types smaller than double to double.
Nowhere will you find "cast each argument to whatever the prototype
specifies."  In particular, nowhere in K&R will you find any notion of
DEMOTING longs to ints, nor will you find the notion of promoting (int)
to (void *).

Yes, I KNOW that the prototype gives the compiler all the information it
needs to correctly DO that cast.  And I'll stop objecting, assuming that
I am WARNED about it.  And I won't object at all when and if "coerce
all arguments to prototype" is standard C.

I'm not asking for much.  Just that when you do me a favor, you let me know.
I may not be able to afford it...

=Ned Horvath=

mce@tc.fluke.COM (Brian McElhinney) (09/10/88)

In article <526@bruce.oz> conybear@bruce.oz (Roland Conybeare) writes:
>From article <5077@fluke.COM>, by mce@tc.fluke.COM (Brian McElhinney):
>> Documenting a bug does not make it a feature (the Require Prototypes option
>> should *require* prototypes for *all* routines; anything less is a bug).
>
>	Ahem!  My version of LSC (2.01) when told to "require prototypes",
>complains about all unprototyped calls, *including* toolbox traps.
>	So while I would agree that not providing prototypes for toolbox traps
>is an omission, I would not call it a bug.

Ahem on myself.  I should have mentioned I'm using LSC 3.0.  Obviously this
has changed since 2.01.  Perhaps LSC 3.1 will have true ANSI prototypes???
Of course, I'd rather have THINK spend their time on a C++ compiler.

And will the debugger be updated to let you look at all stack frames?  LSC's
is the first symbolic debugger I have seen that only lets you look at the top
frame.  Surely I'm not the only one who digs into calling stack frames in
search of the Last Bug...

>P.S. and yea verily, doth lint, in its wisdom, deign to check calls to
>	functions, where such calls be made through pointers?

Only thy return values.  But what else could a K&R lint do?  A true ANSI C
compiler (when there is such a thing) would have to check parameters as well.

> I wish (Oh, how I wish) that LSC would allow me to prototype either types or
> declarations

Oh yes.  But at least LSC 3.0 does something with the prototypes it allows!
MPW C (the last non-beta version) would except ANSI prototypes, and then
silently ignore them.  I'm sure this feature was documented too...


Brian McElhinney
mce@tc.fluke.com

sho@pur-phy (Sho Kuwamoto) (09/10/88)

In article <5125@fluke.COM> mce@tc.fluke.COM (Brian McElhinney) writes:

>And will the debugger be updated to let you look at all stack frames?  LSC's
>is the first symbolic debugger I have seen that only lets you look at the top
>frame.  Surely I'm not the only one who digs into calling stack frames in
>search of the Last Bug...

You can do a stack crawl by clicking in the bottom left hand corner of the
debugging window (the box that tells you what routine the PC is in).  A pop
up menu lets you go back to wherever you want.  Or is this not what you were 
talking about?

-Sho

singer@endor.harvard.edu (Rich Siegel) (09/11/88)

In article <5125@fluke.COM> mce@tc.fluke.COM (Brian McElhinney) writes:
>
>And will the debugger be updated to let you look at all stack frames?  LSC's
>is the first symbolic debugger I have seen that only lets you look at the top
>frame.  Surely I'm not the only one who digs into calling stack frames in
>search of the Last Bug...

	As documented, if you hold down the mouse button on the current
function name, a popup menu gives you the call chain, and selecting an
item from this menu takes you to that procedure. (Assuming, of course, that
you've compiled that procedure with debug tables in.))

R.




Rich Siegel
Staff Software Developer
THINK Technologies Division, Symantec Corp.
Internet: singer@endor.harvard.edu
UUCP: ..harvard!endor!singer
Phone: (617) 275-4800 x305

Any opinions stated in this article do not necessarily reflect the views
or policies of Symantec Corporation or its employees.

mce@tc.fluke.COM (Brian McElhinney) (09/13/88)

In article <326@husc6.harvard.edu> singer@endor.UUCP (Rich Siegel) writes:
>	As documented, if you hold down the mouse button on the current
>function name, a popup menu gives you the call chain, and selecting an
>item from this menu takes you to that procedure. (Assuming, of course, that
>you've compiled that procedure with debug tables in.))

Sorry, I wasn't being clear enough.  I'm aware of that feature, but you can't
get to the complete stack frame.  You cannot look at the related parameters,
or local variables, for that line of code (that's what I meant by stack frame;
the PC is only one part of it).

Another feature I would love to see implemented is known in the UNIX world as
tags (the ctags program).  It would allow you to, say, double click on a
symbol and be taken to it's definition in the source code.

There are many other features on my wish list (two views of the same source
file, smart indentation, better integration with the debugger, etc.), but full
stack frames and tags would make the most improvement in the LSC programming
environment.


Brian McElhinney
mce@tc.fluke.com

singer@endor.harvard.edu (Rich Siegel) (09/13/88)

In article <5154@fluke.COM> mce@tc.fluke.COM (Brian McElhinney) writes:
>
>Another feature I would love to see implemented is known in the UNIX world as
>tags (the ctags program).  It would allow you to, say, double click on a
>symbol and be taken to it's definition in the source code.

	In the editor, Option-double-click on a variable or function name
will take you to the first instance of that name in the file in which it's
defined, assuming that symbol isn't static or a preprocessor name.

R>




Rich Siegel
Staff Software Developer
THINK Technologies Division, Symantec Corp.
Internet: singer@endor.harvard.edu
UUCP: ..harvard!endor!singer
Phone: (617) 275-4800 x305

Any opinions stated in this article do not necessarily reflect the views
or policies of Symantec Corporation or its employees.

dtw@f.gp.cs.cmu.edu (Duane Williams) (09/14/88)

A set of ANSI C prototypes for the ROM routines was created and distributed
long ago by Stew Rubenstein at Harvard.  I suspect that the file is still
available in various Mac archives.  It is no doubt in need of updating since
it was based on Tech Note 45, but that shouldn't be too difficult a job.
-- 
uucp: ...!seismo!cmucspt!me.ri.cmu.edu!dtw
arpa: dtw@cs.cmu.edu