Article 325 of comp.sys.apple2.programmer: Path: ns1.nodak.edu!aardvark.ucs.uoknor.edu!constellation!convex!convex!cs.utexas.edu!uunet!psinntp!dg-rtp!webo!dg-webo!bkahn Newsgroups: comp.sys.apple2.programmer Subject: Re: Orca C errors so far? Message-ID: From: bkahn@archive.webo.dg.com (Bruce Kahn) Date: 03 Aug 1993 18:52:33 GMT Reply-To: Bruce_Kahn@dg.com (Bruce Kahn) Sender: usenet@webo.dg.com (Usenet Administration) References: Organization: NSDD/OpenLAN, Data General Corp., Westboro, MA In-Reply-To: "Seth D. Kadesh"'s message of 30 Jul 1993 08:47:02 EST To: "Seth D. Kadesh" Lines: 966 Ive been keeping an informal list of all Orca C bugs since 1.1. Some are my own but most are off the net from various lists or newsgroups. Ive been offline for about 3 weeks now so I missed the original post about the unsigned vs unsigned int but I can add that in later. To forstall any requests, Ill include my entire list below. It starts w/Orca C 1.1 and goes up to 2.0. If anyone has any I dont have listed, pls let me know... Bruce Known Orca/C 1.1 bugs From herwin@pro-novapple.cts.com (Harry Erwin): 1. lseek is miscoded. It can be patched, but you have to know the parameters to the GSOS seek call. Currently it does an LDA 08, when it should do a LDA from the stack. 2. If j is a long automatic variable, j++ and j-- are mishandled. The stack gets corrupted. Avoid. From neufeld@physics.utoronto.ca (Christopher Neufeld): The compiler makes a mistake when trying to compile: -= or += You should use, instead, = -/+ From acmfiu@serss0.fiu.edu (ACMFIU) += (ie num += strlen (foo);) The system crashed. From gwyn@smoke.brl.mil (Doug Gwyn) Orca/C tries to be a conforming implementation, but it falls short on a number of counts, most notably in preprocessing, type qualifiers, and the library. From acmfiu@serss0.fiu.edu (ACMFIU) Ive briefly found that vprintf() (which everyone knows about) and strtime() (or something like that in ) are not in Orca's libraries. Also, memxxx() is one instance of a buggy library routine (w/data > 64K). From acmfiu@serss0.fiu.edu (ACMFIU) 1. #pragma debug 25 I have a 1400+ line program that this fails in. I mainly use it to check for problems with the stack (i.e My function wants a long and I pass an int). Orca has stack correcting code for this but it is much nicer for you to have a clean program. Now, the error happens when you call a function that accepts no parameters (i.e. void). I can't figure out why this has happened. Several others on AOL have likewise figured this out. On small programs (who knows how many lines here) this #pragma seems to work fine. 2. #pragma optimize -1 This, in my opinion, should never be used. I suggest only using '#pragma optimize 3'. The '-1' will turn off stack repair code. Therefore, if you pass an int value to a routine that accepts a long your program will definitely crash. Too bad '#pragma debug 25' doesn't always work or we could find these things out. Response from toddpw@nntp-server.caltech.edu (Todd P. Whitesel) #pragma lint -1 Will tell you if you're passing the wrong size parameters, if you prototype your functions (a good idea in any case). 3. Prototype all functions This is a real stupid bug. I had two dumb C routines to demonstrate this bug that I sent to Mike. I did not prototype these two functions and, I got an error in the beginning of the second function (at the '{') that said something like 'bad label'. Anyway, when I prototyped the function everything worked fine. As a general rule, I know prototype everything (which should be done anyway). I also had a 22,000+ line program (thank goodness for EMACS and memory) and I decided to see if Orca could handle it. Well, I got numerous errors with '{' and also 'local variable space exceeded' which was also a bug because my local variables would never exceed stack space. 4. Bad code generation This has only happened in one instance but it took several days to find (thank you GSBug) and 5 minutes to fix. I had a C program that, when it would call another function, would never return from that function, even if the function was "void foo(void) { }". This was particulary bothersome. Anyway , I traced through the program with GSBug and found out that Orca/C generated bad code and was destroying the contents of the stack (and thus the address to return to after foo() was executed was destroyed. The simple patch to this was an inline asm routine that saved the contents of the stack and direct page, called the function (in the asm routine via JSL), then restored the stack and direct page. It was vital to JSL to the function, rather than using "foo ()". I have not heard other stories of this happening to anyone and I know my code didn't corrupt the stack (as stated before "void foo(void) { }" didn't work so it wasn't my code). 5. NULL == 0 In many old-style (read K&R) code, you see NULL and 0 intermixed. Well, Orca/C balks at this. I had one program I was converting over from UNIX which had 0 and NULL intermixed. It crashes. I replaced all 0's with NULL's and it worked fine. Personally, I don't think anyone should ever use 0. Response from toddpw@nntp-server.caltech.edu (Todd P. Whitesel) Perhaps this fails because NULL is a long equaling zero and 0 is an int equaling zero. I've noticed that Orca/C fails to do implicit type-conversion in certain cases, and adding L's or (long)'s always fixes the problem. 6. inline asm The inline "asm" feature is nice. Yet it is also buggy. For some reason it doesn't seem to like 'rtl'. I have to use 'dcb 0x6b' in it's place. Now 'rtl' sometimes works. It worked once for me in a 1400+ line program but then when I inserted it into a 3100+ line program (without any changes to the asm code), orca/c balked at me about it. Nothing major but be careful. Response from toddpw@nntp-server.caltech.edu (Todd P. Whitesel) Always works like a charm for me, with one exception: the mini-assembler always puts 16 bit immediates in the generated code -- it appears to only change the immediate operand size after the close bracket of the asm{} and then it uses 8 bit immediates for the rest of the source file! Since I was forgetting to restore the register sizes anyway, fixing my bug circumvented Orca's. 7. Static variables Orca/C v1.0 had problems with this. V1.1 supposedly fixed this but this is not true. In small programs I seems to work. But in programs over 1000 lines it doesn't seem to work. The problem is that the static variables get saved in the ~GLOBALS data segment. However, with these 1000+ line programs the compiler fails to save the variable name in the ~GLOBALS segment and therefore the linker gives you unresolved variable references when you link. This is a real pain. Several others on AOL have encountered this. 8. 'const' type qualifier Orca/C has problems with this. I encountered this a few months back and kinda forget what error I get but Doug McIntyre has also discovered problems with this. Rule of thumb: don't use it, although some of the library .h files have 'const' in it. 9. array indexing The following code will access the last element in a char array: foo[strlen (foo) - 1] = '/' *(foo + strlen (foo) - 1) = '/' These two, however, fail to work, for me anyway, in large programs, again 1400+ lines. To fix the bug, I had to declare a dummy local variable of type 'unsigned long' (even 'int' would do) and then say: foo[strlen (foo) - num] = '/' *(foo + strlen (foo) - num) = '/' This is a particularly troublesome bug because it might just as well apply to indexing other elements of the array (although I know of no other even though I tried). Also, note that this works: foo[strlen (foo) - 2] = '/' This accesses the second to last element. Now you explain this to me? Response from toddpw@nntp-server.caltech.edu (Todd P. Whitesel) foo[strlen (foo) - 2] = '/' try 2L and see what happens. 10. a = (1 == 1 ? 1 : 2) I think this is called the trinary operator but I forget (anyway, you can get the picture by my example). Now, I was porting GNUregexp and Orca gave type mismatch errors on a trinary operator in the code. So I matched all the types and sure enough everything was OK. However, I have had no problems with this. Neverthless, good 'ol if..then solved the problem in the regexp program. Just beware. Response from toddpw@nntp-server.caltech.edu (Todd P. Whitesel) I tried the above expression with nothing else around it and it compiles fine. Try sprinkling parenthesis on the off chance that the order of operators is off; if a is a long then L's are probably a good idea also. 11. Out of memory I have a program that's about 3000+ lines (i think) and when I compile it I get "out of memory" errors which is ridiculous because I have 4 megs of memory. Mike has duplicated this error but has been unable to solve the problem. I had 2 megs once I attempted to port p2c. I had the same problem. Then when I got 4 megs the problem went away. Obviously this is due to memory mismanagement in Orca/C. Beware. From avery@netcom.COM (Avery Colter): I made this complex.h, this little suite of basic arithmetic functions for complex numbers, including a typedef of typedef struct {extended Re; extended Im;} complex; I made a simple little void main (void) to check out the operation, and it worked fine... this test main having all local variables. Then I started hacking out an RLC impedance function, which should take a string of series and parallel placed passive elements, and compute the impedance of the whole setup and the output voltage for each of number of driving frequencies. Instead, I got a big headache. The linker refused to link. Every variable I declared gloablly was lost in the compile. A perusal of the symbol table indicated that these had never gotten there. When I made a large-memory-model setting, the ~GLOBALS segment was one byte long! In addition, with some seperate compiles, I was able to force recognition of almost all the global variables.... Except for one of the structs. The linker was saying: Unresoved reference: ~struct08486 or something. Like the structure's internal definition was not getting into the symbol table. What confuses me is, the standard header files are going just fine, with all the structures they set up, while this piddly thing is breaking the linker. It can't be a syntax error in the code, unless the compiler is completely missing it, because it tests out with no code errors. It's only inside the linker that it gets hosed. From toddpw@nntp-server.caltech.edu (Todd P. Whitesel): Orca seems to be really sensitive about where you put your globals. Try putting all your globals (except private statics) in the front of each source file, after the headers but before the first function. I do this all the time and it works reasonably well. BEWARE OF USING GLOBAL STRUCTS. I've had the compiler generate totally bogus code for accessing global structs directly (with .) -- if you auto the struct or only access the elements through a pointer (as in -> ) then it works fine. From acmfiu@serss0.fiu.edu (ACMFIU): For those of you using Orca/C and Prizm, the following is a bug: void foo (void) { int a; a = 0; while (TRUE) { int b; b = 1; break; } } Under Prizm, you can view the variables of your program. Prizm will allow you to view the variable 'a'. However, it will not allow you to view the variable 'b'. This is apparently a bug in Orca/C's debug code generation. It "should" be fixed in the next release of the compiler (1.2 or >). From toddpw@nntp-server.caltech.edu (Todd P. Whitesel): Orca seems to be really sensitive about where you put your globals. Try putting all your globals (except private statics) in the front of each source file, after the headers but before the first function. I do this all the time and it works reasonably well. BEWARE OF USING GLOBAL STRUCTS. I've had the compiler generate totally bogus code for accessing global structs directly (with .) -- if you auto the struct or only access the elements through a pointer (as in -> ) then it works fine. From neufeld@aurora.physics.utoronto.ca (Christopher Neufeld): fprintf(stderr,"Testing\n"); doesn't work in a long program. I don't have to open the file, it's standard open when run from the shell. If I change it to printf("Testing\n"); everything works. Other weird things include programs which run fine, but if you use the "variables" command (under Prizm) to monitor one of the variables, it immediately crashes Prizm into the monitor, until you rename the variable in the source code. No variable name conflicts were involved. When I had a doubly defined #define argument, it issued the appropriate error message and line and column numbers in the source file, but it echoed the line after the error, which was another #define. From:neufeld@aurora.physics.utoronto.ca (Christopher Neufeld): The "sizeof" function returns the wrong value for floating-point passed parameters of type other than extended. This means that the "fwrite" command, which takes the size of the argument as one of its parameters, writes too many bytes to the disk file, which throws everything off when you try to read it back with the correct "sizeof" values. From: STEIN@UCONNVM.BITNET (Alan Stein): I've been having problems with functions returning values. For example, the following bombed: float f(x) float x; { return (x*x); } void main () { float y; ... y = f(x); ... } While, changing just those lines to the following works fine: void f (x,py) float x,*py; { *py = x*x; } void main () { float x,y; ... f(x,&y); ... } =============================================================================== Known Orca/C 1.2 Bugs From gwyn@smoke.brl.mil (Doug Gwyn): Two of the bugs would not have surfaced in my applications had the SIGNAL.H header (in LIBRARIES/ORCACDEFS) omitted the final "int" parameter specification for the signal() function. Just comment it out to avoid the particular problems that I encountered, until MikeW50 gets around to fixing the compiler. From neufeld@aurora.physics.utoronto.ca (Christopher Neufeld): I've discovered a compiler bug in ORCA/C v1.2. The compiler does not compile extended precision constants in source code properly. It generates double precision numbers, then converts them to extended for insertion into the code. Worse, extended precision arrays seem to fill with nonsense if defined by constants in the source code, ie: extended arr[2] = {1.234567890123456789,9.876543210987654321}; The 'L' flag doesn't help, and the manual mentions that ORCA/C ignores that flag anyway. Other things which don't work: #define M_PI 3.1415926535897932385 used in something like: myval = M_PI; gives wrong results. The solution: the stdlib function "strtod" does work properly, so here's an inelegant solution: #define M_PI strtod("3.141592653589792385",NULL); myval = M_PI; Similar things can be done for initializing arrays. You initialize a string array, and then your program has to take time to convert those strings into extended values. From neufeld@aurora.physics.utoronto.ca (Christopher Neufeld): The sscanf() function doesn't work properly. If a string is assigned which contains a long field, and a later NULL-terminated string is assigned which is shorter than that field, the sscanf() function merrily runs over the null character in its zeal to locate two fields where only one exists. It is supposed to return only a single string and return the actual number of fields read. Instead it gleefully runs across the NULL character to get the fields it needs. In some circumstances it works properly. It seems OK if the string it is operating upon was never any longer than it is at the moment it is called. This is strange. Anyway, here's a code fragment which demonstrates the error, with the output as produced under ORCA/C v1.2 and on a Sun/4. If anybody can suggest a useful workaround, I'd be glad to hear it. I tried copying an extra NULL character after the one already at the end of the string. That had no effect. The problem seems to be that sscanf() is treating the NULL character as whitespace, and so it's skipping it. This has been responsible for it picking up garbage which wasn't ever in the input string, because it kept looking off the end of the memory reserved for the string. For now I'm planning to move to the strtok() function for the things I want to do. It's more natural in my program anyway, but the bug is still a nuisance. #include #include void main() { char test[100]; char s1[100],s2[100]; int n; strcpy(test,"1234567890 ABCDEFGHIJ"); /* sscanf should find two strings */ n = sscanf(test,"%s %s",s1,s2); printf("n=%i, s1=%s, s2=%s\n",n,s1,s2); strcpy(test,"abc"); /* sscanf should find one string */ n = sscanf(test,"%s %s",s1,s2); printf("n=%i, s1=%s, s2=%s\n",n,s1,s2); } Compiled under ORCA/C v1.2 with ORCAGLIB library n=2, s1=1234567890, s2=ABCDEFGHIJ n=2, s1=abc, s2=567890 Compiled on a Sun/4: n=2, s1=1234567890, s2=ABCDEFGHIJ n=1, s1=abc, s2=ABCDEFGHIJ From gt0t+@andrew.cmu.edu (Gregory Ross Thompson): if (foo.bar = spooge[this]) { printf("Cool."); } This should print Cool. Whenever the value being assigned up there is non-zero, right? That's what K&R says, that's what EVERY OTHER COMPILER IN THE UNIVERSE does. That's NOT what Orca/C does. To get Orca to have the same functionality, I had to do: if ((foo.bar = spooge[this]) != 0) { printf("Cool."); } From gwyn@smoke.brl.mil (Doug Gwyn): Bug fixes for ORCA/C release 1.2 (including APW) header files (in ORCACDEFS): To avoid copyright hassles, I show only enough of the context to make the patch. ASSERT.H: #ifndef NDEBUG extern void exit (int status); /* DAG -- was missing */ extern int printf(char *format, ...); /* DAG -- was missing */ #define assert(expression) (((expression) == 0) ? (printf("Assertion failed: file %s, line %d\n", __FILE__, __LINE__), exit(-1)): (void)0) /* DAG -- added cast */ Note that this is still not a fully standard-conforming . The biggest problem is that it doesn't raise(SIGABRT). MISCTOOL.H: #define alreadyInQueue 0x0382 /* DAG -- added following for 5.0.4: */ #define badTimeVerb 0x0390 /* Invalid convVerb value */ #define badTimeData 0x0391 /* Invalid date or time to be converted */ extern pascal void ClrHeartBeat() inline(0x1403,dispatcher); /* DAG -- added following for 5.0.4: */ extern pascal unsigned long ConvSeconds() inline(0x3703,dispatcher); QUICKDRAW.H: #define mode640 0x0080 /* Argument to QDStartup */ #define noFastFont 0x1000 /* masterSCB bit; DAG -- added for 5.0.4 */ SIGNAL.H: void (*signal(int sig, void (*func) (int)))(/*int*/); /* DAG */ int raise(int sig); WINDOW.H: #define tmIdleEvents 0x00100000L #define tmNoGetNextEvent 0x00200000L /* DAG -- added for 5.0.4 */ From meekins@cis.ohio-state.edu (Tim Meekins): Anyone know a good hack around the Orca/C NULL bug. I remember when we discovered it at the programming party last May. I just verified the bug today. The generated code is hilarious and can't possibly work right. I have the following: BLAH *ptr = NULL; and Orca generates: ldx #0 tay ;where did A come from???? bpl lab1 ;this will randomly get taken depending phx ; on whatever A happens to be lab1 pha pla sta ptr ;this value is unknown, not NULL pla sta ptr+2 ;this value is correct. From meekins@cis.ohio-state.edu (Tim Meekins): After a marathon 10 straight hours, I fixed the bad bug that has been driving me nuts for two days. Well, my suspicions were founded, and Orca/C was the culprit. I had a function that had no parameters but Orca was setting up a stack frame for 6 bytes! Strange. I wrote macro which essentially did the following before every call to my function: asm { pha \ pha \ pha } BTW, I tried prototyping with and with out a void. [Follow up via email:] It's the same void bug I've heard others complain, and even others reply back and say that it doesn't exist. My program had nearly 20 voided functions, and about 50 non-void functions. That particular function was the first function in that source file, so maybe something didn't get initialized. I need to verify if this is the problem by moving somewhere else and seeing what happens. Basically, it creates a stack from for the local variables only, since there were no parameters. Upon exiting it restores the local variables and then moves the rtl back 6 bytes and removes an extra 6 bytes as though it were expecting 6 bytes of parameters. I tried using the void statement and not using it. Same problem. From meekins@cis.ohio-state.edu (Tim Meekins): I wanted to see how many characters were in a string segment, so I subtracted the start from the end to get the number of bytes. Orca did the subtraction, then divided the result by 2. Why? for example, char *start,*p; printf("%d bytes used", (int)(p - start)); Orca generated the following (pseudocode): push start sub p div 2 From schwarts@cps.msu.edu (Steven Eric Schwartz): I cannot seem to get longint variables to work and/or store values over 16384. As an example, this program (typing from memory): int i; longint j; for(i = 0; i <= 15; i++) printf("i=%10d\n",1 << i); yields as output: 1 2 4 . . . 16384 -32767 Any ideas on what's wrong? =============================================================================== Known Orca/C 1.3 Bugs From David.Empson@bbs.actrix.gen.nz (David Empson): 1: As I've already told Hisao Kuroda in E-Mail, the problem in this case appears to be a bug with forward references to structures. This bug (in ORCA/C 1.2 and 1.3) causes the compiler to choke if you refer to a structure which hasn't been defined yet, within the definition of another structure. As soon as any code tries to access the forward-referenced structure, you either get an 'illegal forward reference' error, or a compiler crash [I wasn't aware of the latter until I tried this code]. Here is a simple example which demonstrates it: struct a { struct b *bptr; }; struct b { int i, j, k; struct a *aptr; }; int main(int argc, char *argv[]) { struct a var1; struct b var2; var2.i = var2.j = var2.k = 0; var2.aptr = &var1; var1.bptr = &var2; /* COMPILER REPORTS ERROR HERE */ return 0; } The bug can be worked around by adding the line "struct b;" before the definition of "struct a". From benson@vuse.vanderbilt.edu (Paul BaJa Benson): I think it is a compiler bug. Try this quick code: { unsigned long ivar = 0xFFFF; printf("%ld\n", ivar+1); } Now, this code works when compiled without optimization (i.e. returns 0x10000), but set optimize to -1 and it returns a 0. This appears to be the same bug Dave Empson is complaining about (or similar to it). 0xFFFF+1 works in either situation, a variable must contain the FFFF. From uerics@mcl.ucsb.edu (Eric D. Shepherd): Well... I have a program written in ANSI C which does not run after being compiled under Orca/C. I've already had to do some revisions to get it to compile in the first place. But now I'm having strange stack problems: Here's a basic outline of the functions in question: void function1(...) { . . x=function2(); . . while (...) --(*wordary)= some expression (no function calls); . . return x; } The problem is this: this routine crashes on exit. Using strategically placed breakpoints, I found that the stack is in good condition immediately before the while loop, but during the while loop, stuff is being pulled off the stack -- including the return address from function1!! Does this make sense? Why is this happening? From David.Empson@bbs.actrix.gen.nz: Library routine gets() doesn't write anything into a string if an empty line is entered - it should be inserting a \0 terminator byte. Haven't tried fgets() to see if it shares the problem. From David.Empson@bbs.actrix.gen.nz: Library routine fscanf() goes into an infinite loop if whitespace is used in the scan string, and end of file is reached. It appears to be executing the code: while (isspace(fgetc(fp)); and fgetc() is returning -1, which happens to be regarded as a space. See the next bug. From David.Empson@bbs.actrix.gen.nz: Bug in isxxx() macros, hence a bug in the compiler: negative indexing doesn't work if a variable is used to index into the array. Obviously this isn't valid for a standard array, but it is quite legal to use a negative offset from a pointer, writing it as p[-1]. e.g. int a; a = -1; if (isspace(a)) ... which expands to a = -1; if (((__ctype+1)[a] & __space)) ... generates the code lda #$FFFF sta 7 ldx 7 lda _ctype + 1,x This will index 65535 bytes past the end of the table, not to the first byte in the table! isspace(-1) does generate the correct code: lda _ctype This bug also applies to the large memory model - the index is treated as unsigned, whether or not it was a signed variable. The following code doesn't work either: (*((__ctype+1)+(c)) & __space) However, the following does work (since a negative index is no longer used), but generates less efficient code: (__ctype[c+1] & __space) It appears that the buggy code is only generated if the pointer is an array or an array plus an offset. If a pointer variable is involved, different code is used, which also has a bug (see #4). Optimization was off (#pragma optimize 0) at the time this and the next bug were noticed. It appears that Mike forgot or overlooked the fact that LDA absolute,X DOESN'T wrap within the same bank - it moves on to the next bank. From David.Empson@bbs.actrix.gen.nz: Unrelated bug in pointer addition in the SMALL model: adding an int variable or numeric constant to a pointer doesn't update the high word of the pointer, resulting in wraparound within the same bank. Adding a long to a pointer is OK. There is no problem in the large model - the integer is sign extended before the addition. e.g. char *p; int a; p = (char *) 0x02FFFEL; a = 2; p += a; The following code is generated: pei $0002 pei $FFFE lda 1,s sta 07 lda 3,s sta 09 pla pla lda #$0002 sta 0B pei 09 pei 07 lda 0B clc adc 1,s sta 1,s lda 1,s sta 07 lda 3,s sta 09 pla pla This will result in the pointer containing 0x020000, not 0x030000. This bug has a side effect: negative indexing WILL work properly in this case. Note: everything should be fine PROVIDED no data structure crosses a bank boundary. There is no mention of this in the manual (it only says that no data structure should exceed 64k), and I don't know if malloc() requests memory with AttrNoCross set. This isn't a sufficient requirement though, since a toolbox call might return a data structure that crosses a bank boundary (e.g. the resource manager might load a resource which crosses a bank boundary). From David.Empson@bbs.actrix.gen.nz: The compiler locked up while trying to compile this: b = ((*(__ctype+1)(a) & __space)); It should have reported a syntax error or something. From David.Empson@bbs.actrix.gen.nz: Declaring a pointer to a previously undefined structure type causes the compiler to crash and/or produce an "illegal forward reference" error when structure elements are accessed through the pointer. [Already reported to Byte Works.] From David.Empson@bbs.actrix.gen.nz: Toolbox glue code FWEntry passes parameters in the wrong order (should it be declared 'pascal'?). From David.Empson@bbs.actrix.gen.nz: Declared a local char * variable with the same name as a function, and tried to call the function. The compiler hung. char *filesys(word); void show_usage(VolumeRecGS *vrec) { char *filesys; my_printf("(%s)", filesys(vrec->fileSysID)); } From David.Empson@bbs.actrix.gen.nz: Incorrect code is generated for the following: osrc.resourceNumber = odest.resourceNumber += 1; The address of osrc.resourceNumber is not pushed onto the stack, put the code attempts to pull it off to do the second store operation.[new bugs since letter sent] From David.Empson@bbs.actrix.gen.nz: No library glue code for WriteTimeHex call. From dave@mystie.webo.dg.com: Declaring #define A B #define B A A; will cause the compiler to hang. From dave@mystie.weob.dg.com: Declaring: #define A(x) printf(#x) And then using it as A(foo) yields A("foo"). However, using it as A("foo") should yield A(""foo"") but instead yields something like A(")"). From dempson@swell.actrix.gen.nz (David Empson): 1. [Library] If gets() is used and a blank line is entered, nothing is written into the target string (a null terminator should be written into the first byte). I haven't tried fgets(). [Bug also in 2.0] 2. [Library] The FWEntry glue code passes the parameters in the wrong order to the toolbox call, resulting in a crash. [Bug also in 2.0] [Ed.- The following have been fixed in 2.0] 1. [Library] fscanf(), scanf() and sscanf() hung if end of input was reached while skipping whitespace. 2. isspace(var) where var contains -1 (and the other classification macros). ORCA/C 1.3 indexed 65535 bytes past the array and returned a random result. The same applied to any expression of the form *(pointer + var), pointer[var] or array[var], where var contained a negative value. 3. In the small memory model, adding an integer constant to a pointer didn't update the high word of the pointer. This prevented any data structure crossing a 64k boundary (including anything that the toolbox returned to the program, such as a block from NewHandle, or a resource). 4. Compiler hung when compiling the following (erroneous) expression: b = ((*(__ctype+1)(a) & __space)); ORCA/C 2.0 reports several errors (including "Compiler bug"). 5. Wrong code generated for the following (osrc and odest are OpenRecGS structures). osrc.resourceNumber = odest.resourceNumber += 1; (i.e. increment resource number for destination file and copy it to the source file parameter block). The compiler didn't push the address of the first variable, then tried to pull it off the stack later, causing stack corruption. 6. Hex and octal constants from 0x8000 to 0xFFFF were treated as signed long, rather than unsigned int. 7. [Library] gmtime() and localtime() returned the wrong date if the time was exactly midnight on the first of a month. From Reade Glyn Devin (glyn@cs.UAlberta.CA): Although it _should_ work, both Orca/C 1.3 and 2.0 have some problems. Try these in order: 1. try ...(exact_match ? NULL : (unitptr) n))) 2. try ...(exact_match ? (unitptr) NULL : (unitptr) n))) 3. try pulling the above fragment out of the if() statement as a separate function. From Sameer Parekh (zane@genesis.MCS.COM) writes: NULL, as usual, is (void *) n is an array, with the declaration: unit n[MAX_UNIT_PRECISION]; userid_match is a function with the header: static boolean userid_match(char *userid, char *substr,unitptr n); if (userid_match((char *)userid0, (char *) userid, (exact_match ? NULL : n))) ^ The operation cannot be performed on operands of the type given ^ The operation cannot be performed on operands of the type given =============================================================================== Known Orca/C 2.0 Bugs From jmk3@crux3.cit.cornell.edu (Jay Krell): I reported a problem in ORCA/Pascal that remains in C 2.0. The CDev glue code allocates a new ID every time your CDev is loaded. I've seen wierd results from stdio, like lines being output out of order. Mike said this is due to buffering in stdio and the shell. From dempson@swell.actrix.gen.nz (David Empson): 1. [Library] If gets() is used and a blank line is entered, nothing is written into the target string (a null terminator should be written into the first byte). I haven't tried fgets(). [Bug also in 1.3] 2. [Library] The FWEntry glue code passes the parameters in the wrong order to the toolbox call, resulting in a crash. [Bug also in 1.3] 3. Compiler doesn't catch an error in the following. I accidentally used the same name for a global function and local variable, and tried to call the function: char *filesys(word); void show_filesys(word fs) { char *filesys; printf("(%s)", filesys(fs)); } The compiler generates code which calls the character pointer! In version 1.3, the compiler hung when trying to compile the show_filesys function. 4. The parameter structure for the WriteTimeHex call has its fields in the wrong order. In version 1.3, misctool.h claimed that WriteTimeHex was a library routine, but no glue code was provided to call the toolbox, resulting in a linker error. 5. [Shell or Library] Strange problems with standard input. (a) Programs compiled with ORCA/C 1.3 work fine in Shell 2.0.0. (b) Programs compiled with ORCA/C 2.0.0 ignore input redirection in Shell 2.0.0. See also item 6. (c) Programs compiled with ORCA/C 1.3 or 2.0.0 hang with Shell 2.0.1 if input redirection is used. The computer appears to be stuck in a loop inside GS/OS. 6. [Shell or Library] Bug in handling input from .CONSOLE (Shell 2.0.0 and 2.0.1). If output redirection is used with a simple "copy standard in to standard out" program, some CR characters are sent to the wrong destination. When the .CONSOLE formatted read routine is used, the program must output a CR to bring the cursor down to the next line. The CR is being sent to the current output device or file, not to .CONSOLE. This means that extra CRs are written to the output file, and the input lines are tacked on the end of each other. This doesn't happen if the program is compiled with ORCA/C 1.3. 7. [Shell 2.0.1 or ORCA/C 2.0.0] Either of these is causing frequent crashes - I have to reboot after a few compiles. No problem when going back to Shell 2.0.0 and ORCA/C 1.3. Symptom is random memory location getting set to zero, usually in GS/OS or a previously loaded program (such as the Linker). 8. [Compiler] Serious bug in automatic type conversions. If an unsigned integer VARIABLE is added to a long, the compiler generates code to sign extend the unsigned integer. It should be setting the high word to zero, not the sign extension of the low word. Here is an example: unsigned int u = 32768U; printf("65536 + 32768 = %lu\n", 65536L + u); The program should print 98304, but it prints 32768! The program works correctly if an unsigned constant is used. I haven't tried more complex expressions than a constant or a single variable. From Reade Glyn Devin (glyn@cs.UAlberta.CA): Although it _should_ work, both Orca/C 1.3 and 2.0 have some problems. Try these in order: 1. try ...(exact_match ? NULL : (unitptr) n))) 2. try ...(exact_match ? (unitptr) NULL : (unitptr) n))) 3. try pulling the above fragment out of the if() statement as a separate function. -- Bruce Kahn Phone (508) 870-6488 NSDD / OpenLAN FAX (508) 898-4212 Data General Corporation, Westboro MA USA INet: Bruce_Kahn@dg.com Standard disclaimers still apply, even where prohibited by law...