[comp.sys.apple] ORCA/C problems

jb10320@uxa.cso.uiuc.edu (Jawaid Bazyar) (02/07/90)

I just got ORCA/C in the mail and am having a problem with it.  The code
ran fine under APW so I'm thinking it's a compiler bug.  The code in
question leaves excess values on the stack, evidently, and crashes upon
return.  Anyone know of any bugs in ORCA that would do this? (I'm sending
my registration card in tomorrow, Byteworks said they had beta versions
with bug fixes.).

This is a really nice package, and I'd like to use it.
Thanx in advance...

--
Jawaid Bazyar               | This message was posted to thousands of machines
Junior/Computer Engineering | throughout the entire civilized world. It cost
jb10320@uxa.cso.uiuc.edu    | the net hundreds, maybe thousands of dollars.         

rnf@shumv1.uucp (Rick Fincher) (02/08/90)

In article <1990Feb7.034310.5315@ux1.cso.uiuc.edu> jb10320@uxa.cso.uiuc.edu (Jawaid Bazyar) writes:
>I just got ORCA/C in the mail and am having a problem with it.  The code
>ran fine under APW so I'm thinking it's a compiler bug.  The code in
>question leaves excess values on the stack, evidently, and crashes upon
>return.  Anyone know of any bugs in ORCA that would do this? (I'm sending
>my registration card in tomorrow, Byteworks said they had beta versions
>with bug fixes.).

It's not really a bug.  What usually happens is that functions are not
properly typed so the calling routine pulls the incorrect number of
parameters off the stack.  This works in APW because the compiler does
stack repair in cases of bad code like this.  The example in the docs
of the beta upgrade compiler is:

printf("%ld", 2);  /* This is ILLEGAL */

This doesn't work because printf is expecting a long and gets an int.
Four bytes are pulled off the stack when only 2 were pushed.

You can send a note to the Byte Works when you send in your warranty card or
call them and they will send you a beta version of the new compiler that
will generate stack repair code (at the cost of speed).  It is best to get 
that stuff out of your code and compile without this option, then you get 
the best speed.  If you are on America Online send Mike Westerfield a note
(MikeW50) and he will mail you the new compiler online once he has your 
warranty card.  I would go ahead and get it.  The 1.0 compiler has numerous
bugs that can be annoying that have been fixed in the beta release.  You
should get the new final version of the compiler free when it is released. 

>
>This is a really nice package, and I'd like to use it.
>Thanx in advance...

I like it too, there are some differences in APW and ORCA C because of ANSI
standardization but they are minor.  I find that the biggest difference in
my ORCA C code is the replacement of a couple of pages of APW C code with
the startDesk function.  If you isolated all of your startup code in a 
function, though, this will be simple.  You can still manually start your
tools if you want to though.

Rick Fincher
rnf@shumv1.ncsu.edu

wack@udel.edu (Andrew Wack) (02/08/90)

Speaking of ORCA/C bugs, I've got one....(actually 2).  Try the following
program:

#pragma optimize 1
#include <stdio.h>

void main(void)
{
long int x;

x = 1600;
printf("%li \n", x);
x -= 4096;
printf("%li \n", x);
}

What you should get is 1600 and -2496, instead it generates 1600 and 
2^17 - 4096 + 1600 (I forget what it is, but I know how the compiler
is comming up with it).  If you remove the optimize pragma it works
fine.  Also it doesn't help to type-cast the 4096 as (long) (and you
shouldn't have to).  I suspect that when the optimizer is doing its
constant expression evaluation, it generates code to subtract 4096 as
though it were an int, not a long, which would result in the funny
answer.

The reason I say this is two bugs is that I only discovered this one
because the compiler has been giving me the "terminal compiler error" for
a piece of code I've been working on
and sending me back to the text edditor when I compile with no optimiation.
If I turn on optimize 1, the terminal error goes away, but I get the above
funny results.

Actualy I just thought of a third minor bug in the assembly language 
displays...the dissasembler dissasembles a TCS as a TSC (or vice-versa,
I can't remember right now).  This creates a problem when doing debugging
on the desktop at the assembly level, since their emulator follows this 
error!  Makes it kind of tough to save the stack pointer.

Does anybody know if these bugs (primarily the first two) are fixed in the
beta compiler?  I'm really getting tired of wasting time coding around 
these problems.  (Although I must say I'm very impressed by the Desktop and
ORCA/C in general for a version 1.0 product).

--
--------------------------------------------------------------------------------
Andrew Wack                               Gravitation cannot be held responsible
ARPA : wack@udel.edu               for people falling in love -- Albert Einstein

gwyn@smoke.BRL.MIL (Doug Gwyn) (02/08/90)

In article <1990Feb7.034310.5315@ux1.cso.uiuc.edu> jb10320@uxa.cso.uiuc.edu (Jawaid Bazyar) writes:
>I just got ORCA/C in the mail and am having a problem with it.  The code
>ran fine under APW so I'm thinking it's a compiler bug.  The code in
>question leaves excess values on the stack, evidently, and crashes upon
>return.  Anyone know of any bugs in ORCA that would do this?

The biggest problem in ORCA/C 1.0 is that it generates incorrect code
for accessing static variables.  Consequently you should code like this:
	#define	STATIC	/* define as "static" once ORCA/C bug is fixed */
	STATIC my_array[UMPTEEN];
Of course this means that your STATIC variable names acquire external
linkage, so you have to watch out for conflicts with library globals
and with STATIC and extern data in other application modules.

Also make sure only one of ORCALIB or ORCAGLIB is in the LIBRARIES
folder, depending on the "memory model" you tell the compiler to use
(small model by default, thus ORCALIB).

From reading ORCA/C bulletin boards, it appears that the other biggest
cause of stack corruption etc. occurs when programmers fail to use
proper types for functions.  The recommended practice to reduce this
problem is to ALWAYS #include a header that declares full prototypes
for all functions you might call; that way even if you slip up slightly
the ANSI C argument type coercion will fix the type for you.  In the
absence of a prototype, you'll simply pass the wrong format and/or
amount of data on the stack, resulting in havoc.  The usual culprit
here is a 2-byte integer such as 0 being passed where a function wants
a 4-byte pointer.

rlw@ttardis.UUCP (Ron Wilson) (02/09/90)

In article <1990Feb7.171108.553@ncsuvx.ncsu.edu>, rnf@shumv1.uucp (Rick Fincher) writes:
>
>In article <1990Feb7.034310.5315@ux1.cso.uiuc.edu> jb10320@uxa.cso.uiuc.edu (Jawaid Bazyar) writes:
>>I just got ORCA/C in the mail and am having a problem with it.  The code
>>ran fine under APW so I'm thinking it's a compiler bug.  The code in
>>question leaves excess values on the stack, evidently, and crashes upon
>>return.  Anyone know of any bugs in ORCA that would do this? (I'm sending
>>my registration card in tomorrow, Byteworks said they had beta versions
>>with bug fixes.).
>
>It's not really a bug.  What usually happens is that functions are not
>properly typed so the calling routine pulls the incorrect number of
>parameters off the stack.  This works in APW because the compiler does
>stack repair in cases of bad code like this.  The example in the docs
>of the beta upgrade compiler is:
>
>printf("%ld", 2);  /* This is ILLEGAL */
>
>This doesn't work because printf is expecting a long and gets an int.
>Four bytes are pulled off the stack when only 2 were pushed.
>
>You can send a note to the Byte Works when you send in your warranty card or
>call them and they will send you a beta version of the new compiler that
>will generate stack repair code (at the cost of speed).  It is best to get 
>that stuff out of your code and compile without this option, then you get 
>the best speed.  If you are on America Online send Mike Westerfield a note
>
>Rick Fincher
>rnf@shumv1.ncsu.edu

This so-called stack repair should NOT reduce performance - if it doess, then
the compiler writer(s) are to blame.

So far every C compiler I have used performed function calls in the following
way:

	save current stack pointer to a register
	push parameters onto the stack in reverse order
	push saved stack pointer onto the stack
	call the function via JSR (or equiv - this leaves the return
		address on the top of the stack

	when the function returns, pop the saved stack pointer off the stack
		and set the set pointer to this value

In the called function:

	save current stack pointer as a context reference
	access the passed parameters by using an offset relative to the context
		reference  (this might be a LDA X,4 to access a parameter that
		is 4 bytes deep into the stack - for example)

	when returning, either save the return value in a register, or in a
		location relative to the context reference, then simply
		return using a RTS (or equiv)

The called function does NOT attempt to remove the parameters from the stack -
this task is left to the calling function - thus, this isn't so much a "repair"
of the stack pointer - just normal house keeping - it would ONLY be a repair IF
the called function ALSO (tried to) remove the parameters from the stack.

This is a method I first learned about in collage when I took a compilers
class - I have also seen this method used in Pascal, Modula, Ada, and Fortran
compilers - it is also highly recommended by several books on the subject that
I have seen (I have one at home, I can post the name tomorrow) - and it also
appears in several books on assembly language programming.

I do not think that the ANSI standard requires any peticular method of
implementing function calls - it just highly discourages the "traditional"
C method of writing functions to be called with varying numbers of parameters.

For the machines I work with (or at least have worked with), I can't think of
any better method of passing parameters in a way that allows the called
function to be reentrant or recursive - even on a CPU that uses multiple
banks of on-chip registers to allow parameter pasing without memory copying -
you have a limitted number of registers to use, so you have to resort to
using main RAM for long parameter lists; thus this stack idea still applies.

dlyons@Apple.COM (David A. Lyons) (02/10/90)

In article <1990Feb7.171108.553@ncsuvx.ncsu.edu> rnf@shumv1.ncsu.edu (Rick Fincher) writes:
[...]
>I like it too, there are some differences in APW and ORCA C because of ANSI
>standardization but they are minor.  I find that the biggest difference in
>my ORCA C code is the replacement of a couple of pages of APW C code with
>the startDesk function.  If you isolated all of your startup code in a 
>function, though, this will be simple.  You can still manually start your
>tools if you want to though.
>
>Rick Fincher
>rnf@shumv1.ncsu.edu

'course, remember that you can use StartUpTools and ShutDownTools in the
System Software 5.0+ Tool Locator.
-- 

 --David A. Lyons, Apple Computer, Inc.      |   DAL Systems
   Apple II Developer Technical Support      |   P.O. Box 875
   America Online: Dave Lyons                |   Cupertino, CA 95015-0875
   GEnie: D.LYONS2 or DAVE.LYONS         CompuServe: 72177,3233
   Internet/BITNET:  dlyons@apple.com    UUCP:  ...!ames!apple!dlyons
   
   My opinions are my own, not Apple's.

wack@udel.edu (Andrew Wack) (02/16/90)

After spending 6 frustrating hours trying to debug my program I came
upon another ORCA/C bug.  The problem was that after calling a certain
procedure from main, all my variable declared in main were trashed.
Actually, after making this procedure call, the memory locations that
the variables were stored in changed!!  I finally isolated the problem
to the following code fragment inside a while loop in the offending
procedure:

#define FLOOR(A,B) ((long)(A / B) * B)

      if (FLOOR(bs,512) <= (bl_current->length + bl_current->start) )
	 {
	 }

(the define is in for reference)

The problem goes away if I change the <= to <!!  The change doesn't affect
the results of the procedure since I just add 1 to the right hand side of
the inequallity to make it work.  The big question is WHY?

This is really getting quite agrivating..is there a list of known bugs
somewhere?  Does the beta compiler fix these bugs?  When I first bought
this package I was quite impressed....not any more.  This seems like a
pretty obvious bug to make it past testing (then again, so does the
optimize bug that I pointed out a week ago).

At the current rate I am progressing I could have coded this project
in assembly!!

There, I feel better now...any and all help with these problems will be
much appreciated (please, save my sanity).




--
--------------------------------------------------------------------------------
Andrew Wack                               Gravitation cannot be held responsible
Internet : wack@udel.edu           for people falling in love -- Albert Einstein