📄 newvers.txt
字号:
and without user help (provided there are function prototypes). * Function pointers may now be used to call a function without dereferencing. Given a function void f1 (void (*f2) ()) the following was valid before: (*f2) (); The ANSI standard allows a second form (because there's no ambiguity) which is now also allowed: f2 (); * Pointer subtraction was completely messed up and did not work (that is, subtraction of a pointer from a pointer produced wrong results). * Local struct definitions are allowed. * Check types in assignments, parameters for function calls and more. * A new long type (32 bit) is available. The integer promotion rules are applied if needed. This includes much more type checking and a better handling of chars (they are handled as chars, not as ints, in all places where this is possible). * Integer constants now have an associated type, 'U' and 'L' modifers may be used. * The old #asm statement is gone. Instead, there's now a asm ("xxx") statement that has the syntax that is defined by the C++ standard (the C standard does not define an ASM statement). The string literal in parenthesis is inserted in the assembler output. You may also use __asm__ instead of asm (see below). * Allow // comments. * New compiler option -A (ANSI) that disables several extensions (asm directive, // comments, unnamed function parameters) and also defines a macro named __STRICT_ANSI__. The header files will exclude some non-ANSI functions if __STRICT_ANSI__ is defined (that is, -A is given on the command line). -A will not disable the __asm__ directive (identifiers starting with __ are in the namespace of the implementation). * Create optimized code if the address of a variable is a constant. This may be achieved by constructs like "*(char*)0x200 = 0x01" and is used to access absolute memory locations. The compiler detects this case also if structs or arrays are involved and generates direct stores and fetches.3. Known problems----------------- * No floats. * Only simple automatic variables may be initialized (no arrays). * "Wrong" order of arguments on the stack. The arguments are pushed in the order, the arguments are parsed. That means that the va_xxx macros in stdarg.h are ok (they work as expected), but the fixed parameters of a function with a variable argument list do not match and must be determined with the (non-standard) va_fix macro. Using the __fixargs__ kludge, it is possible to write standard conform va_xxx macros to work with variable sized argument lists. However, the fixed parameters in the function itself usually have the wrong values, because the order of the arguments on the stack is reversed compared to a stock C compiler. Pushing the args the other way round requires much work and a more elaborated intermediate code than cc65 has. To understand the problem, have a look at this (non working!) sprintf function: int sprintf (char* buf, char* format, ...) /* Non working version */ { int count; va_list ap; va_start (ap, format); count = vsprintf (buf, format, ap); va_end (ap); return count; } The problem here is in the "format" and "buf" parameters. They do (in most cases) not contain, what the caller gave us as arguments. To access the "real" arguments, use the va_fix macro. It is only valid before the first call to va_arg, and takes the va_list and the number of the fixed argument as parameters. So the right way would be int sprintf (char* buf, char* format, ...) /* Working version */ { int count; va_list ap; va_start (ap, format); count = vsprintf (va_fix (ap, 1), va_fix (ap, 2), ap); va_end (ap); return count; } The fixed parameter are obtained by using the va_fix macro with the number of the parameter given as second argument. Beware: Since the fixed arguments declared are usually one of the additional parameters, the following code, which tries to be somewhat portable, does *not* work. The assignment will overwrite the other parameters instead, causing unexpected results: int sprintf (char* buf, char* format, ...) /* Non working version */ { int count; va_list ap; va_start (ap, format); #ifdef __CC65__ buf = va_fix (ap, 1); format = va_fix (ap, 2); #endif count = vsprintf (buf, format, ap); va_end (ap); return count; } To write a portable version of sprintf, use code like this instead: int sprintf (char* buf, char* format, ...) /* Working version */ { int count; va_list ap; va_start (ap, format); #ifdef __CC65__ count = vsprintf (va_fix (ap, 1), va_fix (ap, 2), ap); #else count = vsprintf (buf, format, ap); #endif va_end (ap); return count; } I know, va_fix is a kludge, but at least it *is* possible to write functions with variable sized argument lists in a comfortable manner. * The assembler still accepts lots of illegal stuff without an error (and creates wrong code). Be careful! * When starting a compiled program twice on the C64 (or 128), you may get other results or the program may even crash. This is because static variables do not have their startup values, they were changed in the first run. * There's only *one* symbol table level. It is - via a flag - used for both, locals and global symbols. However, if you have variables in nested blocks, the names may collide with the ones in the upper block. I will probably add real symbol tables some time to remove this problem. * Variables in nested blocks are handled inefficiently, especially in loops. The frame on the stack is allocated and deallocated for each loop iteration. There's no way around this, since the compiler has not enough memory to hold a complete function body in memory (it would be able to backpatch the frame generating code on function entry).4. Library----------The C library is a complete rewrite and has nothing in common with the oldAtari stuff. When rewriting the library, I was guided by the followingrules: * Use standard conform functions as far as possible. In addition, if there's a ANSI-C compatible function, it should act as defined in the ANSI standard. If if does not act as defined, this is an error. * Do not use non-standard functions if the functionality of those functions is covered by a standard function. Use exceptions only, if there is a non-ANSI function that is very popular (example: itoa). * Use new style prototpyes and header files. * Make the library portable. For example, the complete stdio stuff is based on only four system dependent functions: open, read, write, close So, if you rewrite these functions for a new system, all others (printf, fprintf, fgets, fputc ...) will work, too. * Do not expect a common character set. Unfortunately, I was not able to be completely consequent in this respect. C sources are no problem since the compiler does character translation, but the assembler sources make assumptions about the following characters: 0 --> code $30 + --> code $2B - --> code $2D All other functions (especially the isxxx ones) are table driven, so only the classification table is system dependent.The first port was for the ACE operating system. The current version has alsosupport for the C64, the C128 and the Plus/4 in native mode. The ACE port hasdisk support but no conio module, all others don't have disk support butdirect console I/O.Currently the following limitations the are known: * getwd (ace) does not work. I get an error (carry flag) with an error code of zero (aceErrStopped). Maybe my code is wrong... * The error codes are currently system error codes. They should be translated to something system independent. The ace codes are a good starting point. However, I don't like the idea, that zero is a valid error code, and some other codes are missing ("invalid parameter" and more). As soon as this is done, it is also possible to write a strerror() function to give more descriptive error messages to the user. * Many functions not very good tested. * The printf and heap functions are way too big. Rewritting _printf and malloc/free in assembler will probably squeeze 2K out of the code. * The isxxx functions do not handle EOF correctly. This is probably a permanent restriction, even if it is non-standard. It would require extra code in each of the isxxx functions, since EOF is defined as -1 and cannot be handled effectively with the table approach and 8 bit index registers. * The strcspn, strpbrk and strspn functions have a string length limitation of 256 for the second argument. This is usually not a problem since the second argument gives a character set, and a character set cannot be larger than 256 chars for all known 6502 systems.5. Bugs-------Please note that the compiler and the libraries are beta! Send bug reports touz@cc65.org.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -