grt@twitch.UUCP ( G.R.Tomasevich) (06/25/86)
Our compiler does not need a defined(), or at least I did not try whether it is even accepted. The following example works fine: #if squat||foo int yes; #else int no; #endif main() {} if the 'cc' command includes either '-Dsquat' or '-Dfoo', then 'yes' is selected, else 'no' is selected. E.g.: 'cc -Dfoo -E c.c' System: VAX-11/785 running UNIX 5.2 -- George Tomasevich, ihnp4!twitch!grt AT&T Bell Laboratories, Holmdel, NJ
greg@utcsri.UUCP (Gregory Smith) (06/27/86)
In article <379@twitch.UUCP> grt@twitch.UUCP ( G.R.Tomasevich) writes: >Our compiler does not need a defined(), or at least I did not try whether >it is even accepted. The following example works fine: > >#if squat||foo >int yes; >#else >int no; >#endif >main() {} > >if the 'cc' command includes either '-Dsquat' or '-Dfoo', then 'yes' is >selected, else 'no' is selected. E.g.: 'cc -Dfoo -E c.c' >System: VAX-11/785 running UNIX 5.2 >-- This seems very wrong to me. If foo is defined (as 1), and squat isn't, shouldn't that come out as #if squat||1 which should be rejected by the cpp as containing a non-constant ? What if '#define squat 0' and '#define foo 0' ?? The expression becomes 0||0 which is false. This compiler here (4.2BSD) backs me up on the second point, but not on the first ( i.e. the given example works ). Apparently any symbol in a #if expression becomes '0'. What if squat or foo are defined as something other than a constant? This device cannot replace #if defined(a)|| defined(b) in general. -- "Shades of scorpions! Daedalus has vanished ..... Great Zeus, my ring!" ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg
rbutterworth@watmath.UUCP (Ray Butterworth) (06/27/86)
> Our compiler does not need a defined(), or at least I did not try whether > it is even accepted. The following example works fine: > > #if squat||foo > int yes; > #else > int no; > #endif > main() {} A CPP which silently takes undefined symbols to be 0 can be quite dangerous. Consider the following case with these definitions in a header file. #define squat 10 #define foo 3 /* set to 0 if we don't want to process foos */ Now foo is defined and things work just the way they were intended to. But suppose a year later, a change must be made because in a completely different section of code we now want to handle dynamic foos, and so the definition of foo can no longer be a fixed 3, but must be #define foo (3*y) extern int y; where "y" is an external int which either contains 0, 1, 2, or 3. Now to the person making this change there doesn't seem to be anything wrong with it, as he is innocently unaware of the "#if squat||foo" buried thousands of lines of code away. But what happens when CPP processes this "#if squat||foo" line? CPP will expand this to "#if squat||(3*y)". A broken CPP, such as was recommended, would decide that the undefined token "y" should be 0 and thus produce the "no" case regardless of the value of the external int "y". This is clearly not what the person making the change wanted to happen, nor is it what the person originally writing the "#if" wanted to happen. How long will it be before this newly introduded bug is detected, and how long will it take for someone to figure out what has gone wrong? Possibly a long time if this "#if" is in a seldom-used section of code. A reasonable CPP would would have issued an error that the token "y" is undefined. The problem would have been detected almost immediately and certainly before anything was installed since the code no longer compiles. It would have shown where the problem was, and it would have been trivial for the person making the change to turn the "#if" into a "if(". (Well not in this case since the "int no" isn't executable, but you get the idea I hope.) I think the effort of having to use "#ifdef x" or "#if defined(x)" instead of lazily using "#if x" is well worth it.
guido@mcvax.uucp (Guido van Rossum) (06/29/86)
In article <1063@watmath.UUCP> rbutterworth@watmath.UUCP writes: >A CPP which silently takes undefined symbols to be 0 can be quite >dangerous. [lengthy example deleted] While I agree with your reasoning (the example was quite amazing!), the ANSI C standard declares that undefined identifiers must be made 0. Probably too many people have used this feature so they can't break that existing code :-( Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>
jso@edison.UUCP (07/07/86)
In article <379@twitch.UUCP>, grt@twitch.UUCP ( G.R.Tomasevich) writes: > #if squat||foo > > if the 'cc' command includes either '-Dsquat' or '-Dfoo', then 'yes' is > selected, else 'no' is selected. E.g.: 'cc -Dfoo -E c.c' > George Tomasevich, ihnp4!twitch!grt Fine, since -Dfoo is the same as '#define foo 1', but what about #define foo or #define foo something Do either of these work with #if squat||foo ? I doubt it, since the #if is a *numeric* if. John Owens @ General Electric Company (+1 804 978 5726) edison!jso%virginia@CSNet-Relay.ARPA [old arpa] edison!jso@virginia.EDU [w/ nameservers] jso@edison.UUCP [w/ uucp domains] {cbosgd allegra ncsu xanth}!uvacs!edison!jso [roll your own]
ron@brl-sem.UUCP (07/12/86)
In article <379@twitch.UUCP>, grt@twitch.UUCP ( G.R.Tomasevich) writes: > Our compiler does not need a defined(), or at least I did not try whether > it is even accepted. The following example works fine: > > #if squat||foo Consider an optionally included definition #define SQUAT 0 If your code really wanted to check for this then the proper test would be #if defined(SQUAT) && (squat == 0) to differentiate between undefined SQUAT and SQUAT defined but equal to zero.