On Thu, May 29, 2008 at 09:58:46PM +0100, Jonathan Graham Harston wrote: > I'm updating a C compiler[1] and trying to ensure that it > consistantly predefines certain macros so that source code can be > written to take advantage of that and compile differently for > different targets. It happens all the time. Look at the source for > gcc or infozip or zmodem or kermit or cZ80Tube or loads of code > that is compilable on different platforms, eg: > > #ifdef __riscos__ > setfileattr(fn, load, exec, attr); > #elif __win32__ > writeattr(fn, mdateoff, ro); > #elif __macos__ > filer_setinf(fn, macfdate(mdateoff)); > #endif > etc... This is an example for a very bad idea. Sources with this type of #ifdefs are becoming unmanageable very quickly. Instead of adjusting your code in every place where "setfileattr" is needed, write your own function with semantics defined by you and use this function. This means a lot less #ifdefs and code that is easier to read and to maintain. I know that it is common practice to clutter code with #ifdef, but does not mean it is a good practice. > So, if code wants to be compilable with both cc65 and gcc, then > code has to test for both macros: > > #if (__ATARI__ || __atari__) Again: Bad idea. Using these identifiers is inherently non portable, because you rely on something the compiler maker says. It may change every day and if it does, you have to touch many source files. Instead, use your own #defines with your own semantics. For example, use #ifdef ATARI in your code. You can either set this #define in the makefile when calling the preprocessor. Or you can use your own header file, for example machine.h which does something like this: #if defined(__CC65__) # if defined(__ATARI__) # define ATARI # elif defined(__C64__) ... # else # error "Undefined target system" # endif #else # error "Unknown compiler" #endif With such a file, if compiler semantics change, or if you want to support a new compiler, you have to change ONE file, and not every file. Regarding code like this: > #ifdef __riscos__ > setfileattr(fn, load, exec, attr); > #elif __win32__ > writeattr(fn, mdateoff, ro); > #elif __macos__ > filer_setinf(fn, macfdate(mdateoff)); > #endif > etc... Don't do it. Instead, supply your own set_file_attr() function with semantics defined by you. > Either cc65 and my Small-C should use __platform__, or we behalf > should petition the gcc authors to change gcc to use __PLATFORM__. No. There is no guarantee that there is even something like __PLATFORM__. > Even worse, infozip source code refers to MACOS, MSDOS, UNIX, > etc., but also to __human86k__ and __IBMPC__. Yeah. That's the bad thing with #ifdefs - one looses the overview very quickly. Even worse: A simple change may break code using #ifdefs, because it is very difficult to oversee the effects. And if you aren't testing all the branches of the #ifdef, you cannot be sure it does still work. I've seen code made portable by #ifdefs several times that didn't work because of such problems. Regards Uz -- Ullrich von Bassewitz uz@musoftware.de ---------------------------------------------------------------------- To unsubscribe from the list send mail to majordomo@musoftware.de with the string "unsubscribe cc65" in the body(!) of the mail.Received on Fri May 30 11:10:00 2008
This archive was generated by hypermail 2.1.8 : 2008-05-30 11:10:02 CEST