"Paul D. Smith" <[EMAIL PROTECTED]> 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.
