[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Portability of preprocessor directives
From: |
Paul Eggert |
Subject: |
Re: Portability of preprocessor directives |
Date: |
25 Feb 2003 11:49:17 -0800 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.3 |
"Paul D. Smith" <address@hidden> writes:
> What is the word on portability of preprocessor directives?
>
> I'm in particular thinking of things like "#if defined()",
> "#elif !defined()", the && and || operators, etc.
They've all been in the C language since the late 1970s and in my
experience are quite portable. I have heard of one exception: the
Plan 9 builtin preprocessor does not support "#if" at all, because of
Ken Thompson's personal preference. However, I don't think this is
worth worrying about: anybody porting GNU code to Plan 9 and/or
Inferno will use the ANSI C preprocessor (cpp) to work around this
incompatibility.
Some people prefer "defined (FOO)", but the more typical style in GNU
programs is "defined FOO"; it's just as portable, and it's shorter.
Some compilers, including GCC, optionally issue a diagnostic if you
use "#if FOO" when FOO is not defined. However, it works correctly
(i.e., FOO evaluates to 0) on all compilers that I know of. I don't
worry about this issue in my code, but if you want to worry about it
you can write "#if defined FOO && FOO" instead.
You must use "defined" directly within an #if directive. In other
words, you cannot do this:
#define FOO (! defined BAR)
and expect FOO to evaluate to 0 when BAR is defined, and 1 otherwise.
Instead, you must do something this:
#ifdef BAR
# define defined_BAR 1
#else
# define defined_BAR 0
#endif
#define FOO (! defined_BAR)
though this doesn't have quite the same semantics, since it determines
the value of FOO at FOO's definition, not at FOO's use.
The original traditional C preprocessor did not support #elif, but
compilers without #elif are long dead and are no longer worth worrying
about.
The original traditional C preprocessor required '#' to be in column
1. Typical GNU programs still put '#' in column 1, but I think this
is now more of a style thing than a requirement. If you're worried
about older compilers then it might be best to stick with the style
for a few years more, anyway.