[comp.lang.c] VAX C Preprocessor bugs & workaround

adrian@mti.mti.com (Adrian McCarthy) (01/05/90)

While trying to port some C code from a Unix environment to VAX C, I noted
the following annoyances/bugs(?) in how the VAX C preprocessor handles
various situations.  Read on for explanations *and a workaround*.

Example input:-------------
#define AST *
#define P(x) /AST x AST/

P(Sample Comment)

#ifdef X
#ifdef Y
/* Another comment */
#endif
#endif
main() { }
---------------------------

If you look at the preprocessor output of this file, everything looks
hunky-dory.  If you try to pass through the compiler, though, you're
hosed.

Although the instance of the P() macro "P(Sample Comment)" is expanded
correctly to "/* Sample Comment */", it apparently happens *after* the
comment stripping occurs, since the compiler starts complaining about
unexpected slashes and asterisks.  (This arose when an author tried to make
his/her code palatable to Classic and ANSI implementations of the compiler
by optionally commenting out some parameter prototyping.)

The second problem is that the nested #ifdef's aren't handled as you might
expect.  The "Guide to VAX C" manual states:  "If the condition is false,
then the lines between the #if, #ifdef, or #ifndef and an #else, (or #elif)
or #endif directive are ignored." [p. 10-14]  It is unclear, however, which
#endif the preprocessor will use.  In the case that the outer #ifdef is
false, the *first* #endif is selected, leaving you with an unbalanced
#endif.  (The extra #endif does *not* show up in the preprocessor output,
which makes the following workaround viable.)  Harbison/Steele

Here is a relatively clean workaround that solves both of these problems
without changing the code:
(1) Invoke the compiler once with the /PREPROCESSOR_ONLY qualifier, then
(2) invoke it again on the output from step one.  For example:

  $ cc/preprocessor_only myfile.c
  $ cc myfile.i

For you MMS/Make aficianados [sp?]:
  myfile.obj : myfile.i
           cc myfile.i
  myfile.i : myfile.c
           cc/preprocessor_only myfile.c
(Of course, you can generalize these.)

In the case of nested #ifdef's, you have to be careful about lines
between the #endif's.


Aid.