preprocessor bug

James C Burley burley at world.std.com
Sat Sep 15 00:02:49 AEST 1990


In article <452 at taumet.com> steve at taumet.com (Stephen Clamage) writes:

   erik at tcom.stc.co.uk (Erik Corry) writes:

   >(I am not interested in hearing comments on #define TRUE -1. It
   >is irrelevant.)

   Sorry, I'm going to comment anyway.  Because not all compilers are ANSI-
   conforming, and because among buggy ANSI compilers and non-ANSI compilers
   there are differences in preprocessor behavior, it is safer to use
	   #define TRUE (-1)
   This will prevent the above class of problem from occurring with any kind
   of preprocessor.  Because -1 is an expression (negation of constant 1),
   it should for safety be enclosed in parentheses, just as you would with
	   #define SUM (b + c)
   -- 

   Steve Clamage, TauMetric Corp, steve at taumet.com

I think people would be best advised to #define <whatever> (-1) even when
using true ANSI compilers -- it avoids any possibility of any kind of
nearby operators changing the precedence.  I can't see any useful case of
this in C at this point, looking at my precedence chart, but it is a good
habit to get into -- parenthesize your macros to ensure that the precedence
you want is the precedence you'll get.

The #define SUM (b + c) is another good example.  In this case, it seems ok
because (I assume) b and c are not themselves macros (beyond simple
constants, perhaps).

But suppose you do

#define SUM(b,c) (b + c)

Seems ok, right?  Well...now consider this invocation:

SUM(bool ? 5 : 4,i)

This expands to

(bool ? 5 : 4 + i)

Which is equivalent (in terms of precedence) to:

(bool ? 5 : (4 + i))

Hardly what is expected.  Replace the macro definition with

#define SUM(b,c) ((b) + (c))

And you end up with what you expect:

((bool ? 5 : 4) + (i))

This serves to illustrate two very important points about C macros: 1) Use
parentheses to enclose any entity within the expansion that is not a
"constant" (i.e. either an argument of the macro or itself another macro that
might not have its own parentheses); 2) Switch to C++ and use inline functions
instead, where things are much clearer!  (-:

James Craig Burley, Software Craftsperson    burley at world.std.com



More information about the Comp.lang.c mailing list