Path: news.uiowa.edu!hobbes.physics.uiowa.edu!math.ohio-state.edu!uwm.edu!news.alpha.net!news.mathworks.com!gatech!news.sprintlink.net!demon!contech.demon.co.uk!Sbehrens From: Soenke Behrens Newsgroups: comp.sys.apple2.programmer Subject: ORCA/C buglist v2.6o Date: 17 May 1995 22:20:09 +0100 Organization: Conner Peripherals (UK) Ltd. Lines: 684 Sender: news@news.demon.co.uk Message-ID: <251418847wnr@contech.demon.co.uk> Reply-To: Sbehrens@contech.demon.co.uk NNTP-Posting-Host: dispatch.demon.co.uk X-Newsreader: Newswin Alpha 0.7 X-Posting-Host: contech.demon.co.uk Hi, first there's nothing for a few months, then we swamp you again ... must be a biorythm of ORCA/C bugs. Soenke ================== Bugs in ORCA/C 2.0.3, v.2.6o ======================= Last update 17/05/1995 Compiled by Soenke Behrens, sbehrens@contech.demon.co.uk Preface ======= These are bugs in ORCA/C 2.0.3 (compiler version 2.0.2) found by various users. All of these have already been reported to The Byteworks. The purpose of this document is to help you when programming the GS, so that by knowing about problems in your tools, you can work around them. It is NOT intended to help you bash ORCA/C on grounds of it having bugs. Every product has bugs, and a C compiler is no exception. Note that only a few of the bugs listed here could be entitled "hardcore", the rest range from "annoying" to "mildly amusing". --> Support those that support you!! <-- If you have discovered a bug in ORCA/C and you would like it included in this list, drop me e-mail at sbehrens@contech.demon.co.uk. Soenke Behrens P.S.: An archive containing the code to reproduce most of the bugs is available on request. Be aware that most of the code is quick'n'dirty, and some of it will (naturally) crash your machine. Changes for v.2.6o ================== - Added a section for bugs in the ORCA/C manual - Added the bug about manual page 263 giving a wrong reference. - Added the bugs about manual page 40 failing to mention the pre-processing done before calling NDA init, and describing NDA action incorrectly. Thanks to Peter Watson for reporting them. - Added the bug about ORCA/C not flagging an old-style struct argument in a new-style function definition as an error. Thanks to Peter Watson for reporting it. - Added the bug about ORCA/C not accepting "-1" as a value for "period" in #pragma nda. Thanks to Peter Watson for reporting it. - Added the bug about printf() printing "0x" for a value of 0, precision of 0 with specifier x and modifier #. Compiler bugs ============= - ORCA/C does not accept "-1" as a value for "period" in "#pragma nda", although documentation says it would. 0xffff works, though. [problem38.c] pw - ORCA/C does not flag an error if you mistakenly include an old-style struct parameter in a new-style function definition, like this: void foo (int x) struct bar = {1,2}; { return; } [problem37.c] pw - ORCA/C generates code that will assign garbage and crash your machine if you do: void *p, *q = 0xdeadbeef; p = (1) ? 0 : q; Using p = (1) ? 0x0L : q; instead works as expected. [problem34.c] dr - ORCA/C does not capitalize pascal identifiers in inline assembler. I.e., this won't link: pascal needsomeasm (void) {return;} asm main (void) {jsl needsomeasm} [problem32.c] jk - If you compile a C source file indirectly through #append (like occ 1.12 does for example), ORCA/C does not create a .sym file. It also does not update the value of __LINE__ correctly, causing debuggers to get out of sync. This is more a feature than a bug, I guess. sb - Say you have a struct declaration like: struct foo { struct foo *next; } and you do struct foo var; var.next = NULL; and you turn COP debugging on (#pragma debug -1), then the compiler will crash your machine. [problem30.c] sb - Large integer (non-hex) constants wreak havoc with ORCA/C. I don't know all the possible problem spots, some are: o Assign a value > 0x80000 to a double with a constant, and convert that back to (unsigned long). You will get 0x80000. Like: double f = 2147483649.0; unsigned long j = (unsigned long) f; /* 0x80000 when printf()ed */ o Assign a value > 0x80000 to an unsigned long ... ORCA/C mistakes it as signed again. I didn't really do a lot of tests, as the circumstances seem to be confusing ... there are instances where values > 0x80000 work just fine, and others where they don't ... so ... *shrug*. [problem29.c] pv - The compiler complains with "identifier expected" when doing something like: typedef char *ptr; typedef void *vptr; #define ptr vptr It should not care, since the preprocessor is a simple text substitution system. [problem28.c] jk - The compiler does not like whitespace other than tabs or spaces between the name of a macro taking parameters and its parameters. In other words: A macro call and its parameters have to be on the same line. [problem27.c] jk - If you try to ignore the return value of a tool call that returns LongWord via (void), the value is _not_ pulled off the stack. Not coding (void) and simply ignoring the return value gets rid of the problem. [problem24.c] de - If you have a local variable that is defined with the same type as the return type of a function of the same name, and you call the function in the scope of the local variable, ORCA/C generates code to call the variable instead of flagging an error. [problem23.c, ORCA/C froze instead of generating code] de - Given `char *ptr = (char *)0x00C000;' and `int offset = -32768', the expression `ptr + offset' does not yield 0x4000 as expected. The problem seems to be with ~MUL2, which gives garbage results when one of the operands is -32768 and the other 1 (it may produce garbage for other operands, too). [problem10.c] de - ORCA/C treats variables with type specifier `unsigned' as `signed int'. The solution is to use `unsigned int' instead of `unsigned'. [problem1.c] de, others - The bit-shift operators sometimes "forget" that their left-hand operand is unsigned and treat it as if it were signed. This can also happen with divisions, or other binary operators. Some examples: printf("%d == %d\n",0x8000U << 1, 1U << 16); prints '0 == 1'. Both of the below give 65535, not 32767 as expected: ~1U >> 1 (65533U+1U) / 2 When using non-prototyped functions, 4 bytes may be passed instead of 2 when doing something like: expects_int (0x8000|1); [problem8.c] de, jk, others - The preprocessor operator '##' will not work if used more than once in a row. I.e., bar##foo will work, but bar##foo##gork will give you "barfoo gork". [problem20.c] sv - If you have a pointer to a struct with say two longs in it, the struct is global, and you do something like: a->b = a->c = 0L; then 'a->b' is not assigned 0 but a bogus value. This might happen in other circumstances too, so beware. [problem14.c] dt - Do NOT mix old-style function definitions with prototyped declarations. Passed parameters will be garbled if you attempt that. (I.e. don't do 'void foo (int *);', 'void foo (bar) int *bar;') [problem2.c] sb - If the last statement that goes into creating the .sym file is #endif, and the .sym file already exists, ORCA/C will complain about "no matching #if for this #endif". Example: #ifdef APPLE2 #include #endif [problem17.c] jk - If you have an 'asm' statement with immediate addressing inside a block of conditional code that uses #ifdef, and the condition is not satisfied, you get an error "illegal character" about the '#' in the asm statement. Example, assuming `AppleIIGS` is NOT defined: #ifdef AppleIIGS void bar (void) { asm { lda #10 } } #endif [problem18.c] ma - If you have a struct foo (with two ints, in this case), and you define an array of it like: static const struct foo bar[] = { { 0, 0}, { 1, 1}, }; ORCA/C will not be happy. Use "static struct foo bar[] = {" instead. [problem12.c] sb - Also, ORCA/C will not be happy if you chant struct foo const bar [] = Leave out the 'const' and everything's dandy. [problem13.c] sb - ORCA/C does not like you to typedef an enum before you define it. Do it the other way round. [problem11.c] sb - For this bug, I guess I'll have to display some code: /* * This code shows two problems. The first while() loop acts more as * if its body were 'nedges[*(++sp)]++', not 'nedges[*sp++]++'. * The second while() loop produces an int math error. */ #include #include #pragma debug 25 int main (int argc, char *argv[]) { short *sp; short R_arg[6] = { 0, 1, 2, 3, 4, -1 }; static short S_arg[6] = { 0, 1, 2, 3, 4, -1 }; short nedges[5] = {0,0,0,0,0}; sp = S_arg; while (*sp >= 0) { printf ("sp: %p *sp: %d nedges[*sp]: %d\n",sp,*sp,nedges[*sp]); nedges[*sp++]++; } sp = R_arg; while (*sp >= 0) { printf ("sp: %p *sp: %d nedges[*sp]: %d\n",sp,*sp,nedges[*sp]); nedges[*sp++]++; } return (EXIT_SUCCESS); } [problem5.c] sb Library bugs ============ - printf("[%#.0x]", 0) should print "[]", instead it prints "[0x]". See ISO-C 7.9.6.1, about the '#' modifier and 'x' specifier. [problem36.c] sb - fails to define the type size_t and the macro NULL. It violates namespace by defining CLK_TCK. [time.h] sb - declares several functions to take non-const arguments where they should take const arguments. These are, in detail: Only argument of asctime(), ctime(), gmtime() and localtime(). The change to const arguments can be made without breaking existing library code. [time.h] sb - fails to declare the function strftime(), the library does not implement it. [time.h] sb - declares several functions to take non-const arguments where they should take const arguments. These are, in detail: First argument of memchr(), strchr() and strrchr(). First two arguments of strncmp(). Both arguments of memcmp(), strpbrk(), strcmp(), strspn(), strcspn() and strstr(). Second argument of strcat(), strncat(), strcpy(), strncpy(), strtok(), memcpy() and memmove(). Only argument of strlen(). The change to const arguments can be made without breaking existing library code. [string.h] sb - declares the function srand() to take an argument of type int, it should be unsigned int. The change to unsigned int can be made by the user without breaking existing library code. [stdlib.h] sb - violates namespace by defining the macros clalloc(), cfree(), mlalloc() and relalloc(). [stdlib.h] sb - declares several functions to take non-const arguments where they should take const arguments. These are, in detail: Only argument of atof(), atoi(), atol() and system(). First argument of strtod(), strtol() and strtoul(). First two arguments of bsearch(). The change to const arguments can be made without breaking existing library code. [stdlib.h] sb - fails to declare the functions getc(), putc(), rewind() and setbuf(). The library fails to implement these: Only the macro overrides of these functions are available. [stdio.h] sb - The macro overrides for the functions getc(), putc(), rewind() and setbuf() are not safe; they make references to functions that are neither "secret" (beginning with a '_') nor the name of the function they override. This would lead to wrong behaviour in a (admittedly perverse) situation like: #include #undef fgetc int main (void) { FILE *foo = fopen("abc","r"); int fgetc = getc(foo); /* GIVES A STRANGE ERROR MESSAGE */ return 0; } [stdio.h] sb - violates namespace by defining the macro SYS_OPEN and declaring the variables sys_nerr and sys_errlist. [stdio.h] sb - declares several functions to take non-const arguments where they should take const arguments. These are, in detail: Only argument of perror(), remove() and puts(). Both arguments of rename() and fopen(). First two arguments of freopen() and sscanf(). Second argument of fsetpos(), fprintf(), sprintf(), and fscanf(). First argument of fwrite(), fputs(), printf() and scanf(). The change to const arguments can be made without breaking existing library code. [stdio.h] sb - declares a function va_end() instead of defining a macro va_end(). [stdarg.h] sb - incorrectly declares its functions to take arguments of type extended and return extended when they should be double. The change to double cannot be made without changing the library code. modf() is declared to take a second argument of type pointer to int when it should be pointer to double. The header violates namespace by defining the macro arctan(x). [math.h] sb - The assert() macro does not print out the expression it evaluated in the case of that expression yielding zero (an "error" occuring). [problem35.c] sb - incorrectly declares tolower() and toupper() to take arguments of type char when they should be int. The change to int can be made by the user without breaking consistency with existing library code. [ctype.h] sb - fails to declare the functions isalnum(), isalpha(), iscntrl(), isdigit(), isgraph(), islower(), isprint(), ispunct(), isspace(), isupper() and isxdigit(). The library fails to implement them: Only the macro overrides of these functions are available. [ctype.h] sb - fails to define the typedef sig_atomic_t, which should be int or unsigned int. [signal.h] sb - incorrectly declares fputc(), putchar() and ungetc() to take arguments of type char when they should be int. The change to int can be made by the user without breaking consistency with existing library code. [stdio.h] sb - isgraph() returns a non-zero value for ' '. [problem31.c] jp - memchr() does not return NULL as it should if you make it search for a character in a range >= 64k, and that character does not appear in that range. [problem26.c] jk - stdin doesn't echo 'CR' characters correctly to .CONSOLE (when using getchar(), for example), it echos them to stdout. This seems only to be a problem when in ORCA/Shell, it works as expected with GNO/ME. [problem22.c] de - The toolbox glue code for FWEntry passes parameters in the wrong order (ADDRESS,X,Y,A instead of A,X,Y,ADDRESS). [problem25.c] de - The `HexTime' struct in has its fields backwards, so that the seconds will end up as the month when passed to WriteTimeHex(). [problem21.c] de - If you use the FPE SysFloat library in conjunction with #pragma float, arithmetic with double values will give horrid rounding errors. Using extended or float cures the problem. [problem33.c] df - 'sscanf("foo","%d",&bar);' returns 1 as if it had correctly converted an integer. [problem4.c] sb - 'sscanf("R A 3 0 4","%*[^PR]%c %c %d %d %d",&l,&q,&k,&m,&n),' returns 5. It should return 0, as '%*[^PR]' was not satisfied. [problem6.c] sb - Open a file with mode "rb+". Read a character, step back one char with fseek, write one character, and close the file. You will notice that the file has not changed. The changes are written out correctly if you write more than just one character, though. [problem15.c] pw - Open a file with mode "r+". Read the first line, fflush the file, write a line, and close the file. The file didn't change. To make it change, fseek(fp,0,SEEK_CUR) instead of fflush(fp). [problem16.c] sb Manual bugs =========== - Page 263 references a discussion on NDAs on page 58. This discussion begins on page 40. [ORCA/C manual] sb - Page 40 fails to mention that ORCA/C free()s all allocated memory prior to calling the NDA init() function for NDA shutdown (parameter zero). [ORCA/C manual] pw - Page 40 incorrectly describes the NDA action() function as taking one parameter and returning void, page 41 has the sample code wrong. The action function returns a two-byte value and takes two arguments, like this: boolean ACTION(GrafPortPtr, int); [ORCA/C manual] pw Deviations from ISO/C ==================== These are not bugs, but are areas where ORCA/C deters from the standard on purpose. - ORCA/C does not implement the header . Consequently, the functions mblen(), mbstowcs(), mbtowc(), wcstombs() and wctomb() are missing from , as well as the type wchar_t, which is included in , however. does not declare strcoll() or strxfrm() for the same reason. [stdlib.h, string.h] sb - ORCA/C does not support more than 3 digits for a hexadecimal digit constant invoked with '\x'. Example: The string "\x0077" should be a string consisting of the single character 0x77. In ORCA/C, that string consists of the character 0x07 followed by '7'. [problem19.c] dh - ORCA/C requires that functions that use consume all arguments they got before returning. It also requires that printf() and scanf() consume all arguments they get. Therefore, something like 'printf("%d",i,k);' is not legal with ORCA/C. [plauger.varargs, problem9.c] sb - ORCA/C does not support tentative definitions. Thus, you may not use 'extern int foo = 0;' nor may you have two 'int foo;' definitions in the same source-file on the same scope. [problem7.txt, problem7.c] sb Names and mapping initials ========================== (or: Who made this list possible?) Dave Huang --- dh David Empson --- de Derek Taubert --- dt Devin Reade --- dr Dirk Froehling --- df Jason Perez --- jp Jay Krell --- jk Matt Ackeret --- ma Peter Watson --- pw Philipp Vandry --- pv Soenke Behrens --- sb History of this file ==================== Changes for v.2.6o ================== - Added the bug about printf() printing "0x" for a value of 0, precision of 0 with specifier x and modifier #. Changes for v.2.5o ================== - Moved the changes section to the end of the file, leaving just the most recent changes at the top. - Added a section that maps initials to names of reporting persons ... this whole thing is growing out of proportion and getting hard to track. - Added the bug about declaring some functions incorrectly (not taking "const" arguments), omitting the definitions of size_t and NULL as well as the declaration for strftime() and violating namespace. - Added to the section explaining ORCA/C's lack of and wide-character functions. - Added the bug about declaring some functions incorrectly (not taking "const" arguments) and violating namespace. - Added the bug about declaring some functions incorrectly (not taking "const" arguments), declaring srand() incorrectly and violating namespace. - Added the bug about declaring some functions incorrectly (not taking "const" arguments), violating namespace, not declaring certain functions and defining unsafe macros for these. - Added the bug about not defining a macro for va_end(). - Added the bug about declaring its functions incorrectly and violating namespace. - Added the bug about the assert() macro not printing its expression. - Added the bug about declaring tolower() and toupper() to take char arguments instead of int. - Added the bug about not declaring the "isxxx" functions, and the library not implementing them. - Added the bug about not defining the typedef sig_atomic_t. - Added the bug about declaring fputc(), putchar() and ungetc() to take char arguments instead of int. Changes for v.2.4 ================= - Added the bug about ORCA/C creating wrong code for a 0 -> pointer conversion in a conditional "?" statement. Thanks to Devin Reade. Changes for v.2.3 ================= - Added the bug about ORCA/C not capitalizing pascal identifiers in asm statements. Thanks to Jay Krell. Changes for v.2.2 ================= - Added the bug (?) about ORCA/C not creating a .sym file if you #append a C file. - Went through the list with ORCA/C 2.0.2. No changes were necessary. Changes for v.2.1 ================= - Added the bug about isgraph() returning true for ' '. Thanks to Jason Perez. - Added the fact that ORCA/C lacks . Changes for v.2.0 ================= - Added initials of reporting person to each bug for better tracking. - Went through the list with ORCA/C 2.0.2a1 ... no changes were necessary. - Added the bug about compiler crashing when creating debug code for accessing "recursive" pointers in structs. Changes for v.1.9 ================= - Added the bug about constants > LONG_MAX. Thanks to Philipp Vandry. - Added another instance of the "ORCA/C mistakes unsigned expression for signed" bug. Thanks to Jay Krell. - Added the bug about ORCA/C not allowing line breaks when using macros with parameters. Thanks to Jay Krell. - Added the bug about memchr goofing with ranges >= 64k. Thanks to Jay Krell. - Added the bug about typedef and #define conflicting. Thanks to Jay Krell. Changes for v.1.8 ================= - Added the bug about return values of tool calls not being pulled properly from the stack if you (void) them. Thanks to David Empson for reporting it. - Added the bug about ORCA/C trying to call variables in certain circumstances. Thanks to David Empson for reporting it. - Added the bug about standard input not echoing characters correctly when in ORCA/Shell. Thanks to David Empson for reporting it. - Added the bug about wrong argument order for FWEntry. Thanks to David Empson for reporting it. - Added the bug about . Thanks to David Empson for reporting it. - Added the bug about ~MUL2 fouling up (for example) pointer arithmetics. Thanks to David Empson for reporting it. - Added the correct explanation of the bit-shift problems. Thanks to David Empson for explaining it. - Added the correct explanation of ORCA/C's troubles with 'unsigned' variables, and deleted the "symptom bugs" in the process. Thanks to David Empson for explaining it. - Divided the bug list into a section for compiler bugs and library bugs. - Added the bug about ## and the preprocessor. Thanks to Stefan Voss for reporting it. - Added the fact that ORCA/C deters from the standard when it comes to hex digit constants inside strings. Thanks to Dave Huang for pointing it out. - Added the name of the file to explain and/or reproduce each bug in square brackets (only for my reference). Changes for v.1.7 ================= - Added the bug about assigning 0L to longs in a struct. Thanks to Derek Taubert for reporting it. Changes for v.1.6 ================= - Added the bug about double and FPE support. Thanks to Dirk Froehling for reporting it. Changes for v.1.5 ================= - Added the bug about using "struct foo const bar [] =" - Added the bug about fflush() not making file writes possible Changes for v.1.4 ================= - Added the bug about using "static const struct foo bar [] =" - Added the bug about typedef'ing an enum before defining it Changes for v.1.3 ================= - Added the bug about not using '#' in conditional asm statements. Thanks to Matt Ackeret for reporting it. Changes for v.1.2 ================= - Added the bug regarding .sym files and #endif. Thanks to Jay Krell for reporting it. Changes for v.1.1 ================= - Added the bug about mode "rb+". Thanks to Peter Watson for reporting it. - Added a section for deviations from the ISO/C standard. -- Conner European Technical Support ! Technical Support Telephone: +44-1294-315333 Telefax: +44-1294-315262 ! USA + Canada: FaxBack: +44-1294-315205 BBS: +44-1294-315265 ! 1-800-4CONNER All opinions expressed above are solely my own