Path: utzoo!attcan!uunet!world!burley From: burley@world.std.com (James C Burley) Newsgroups: comp.lang.c Subject: Re: preprocessor bug Message-ID: Date: 14 Sep 90 14:02:49 GMT References: <31530015@hpcvia.CV.HP.COM> <141513@sun.Eng.Sun.COM> <1982@jura.tcom.stc.co.uk> <452@taumet.com> Sender: burley@world.std.com (James C Burley) Organization: The World Lines: 61 In-Reply-To: steve@taumet.com's message of 13 Sep 90 15:20:00 GMT In article <452@taumet.com> steve@taumet.com (Stephen Clamage) writes: erik@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@taumet.com I think people would be best advised to #define (-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@world.std.com