Re: [cc65] Re: Macro naming

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2008-05-30 11:09:51
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