[comp.sys.acorn] C release 3 preprocessor bug ??

mybg@doc.ic.ac.uk (M Y Ben Gershon) (05/16/91)

Am I crazy, or is there a subtle bug in C release 3?  I am surprised that
nobody has mentioned it so far, but the ANSI standard, as far as I can
gather, states that if a preprocessor macro is undefined, it is deemed to
have a value of 0 (in fact 0L, to be precise).  According to the latest K&R,
(which is the ANSI version), and Harbison & Steele, a macro defined as being
0 is identical to a macro which is undefined, as above.  However, Cv3 treats
them differently:  If a macro is defined as:

    #define VAX 0

and we then do:

    #ifdef VAX
    #error VAX is defined!
    #endif

the error message will be displayed.  By the way, who noticed the section on
page 406 of the manual, which describes the use of a pragma to effectively
give user-defined non-serious errors?  I have just noticed it, and find it
very useful!

This behaviour seems to be highly non-standard.  I discovered it when
working on a port from Unix, and it took a long time until I realised that a
preprocessor macro was defined, but equal to zero - which the Acorn compiler
seems to treat differently to an undefined macro.  Does anyone from Acorn
wish to comment on this?

Michael Ben-Gershon

mybg@doc.ic.ac.uk

dbh@doc.ic.ac.uk (Denis Howe) (05/17/91)

In article <1991May16.125325.15323@doc.ic.ac.uk> Michael Ben-Gershon
<mybg@doc.ic.ac.uk> asks:
>Am I crazy, or is there a subtle bug in C release 3?

You cannot be that crazy if you use an Arc, but then again, you are at
Imperial ;-)

My understanding of the C pre-processor which agrees with that of cpp
of SunOS 4.1 here and HP-UX (both /lib/cpp and /lib/cpp.ansi) is that
an undefined macro is only 0 in pre-processor evaluated expressions
(after #if, as opposed to #ifdef) so if UNDEFINED is not defined:

	#if UNDEFINED == 0
	This will be included.
	#endif
or
	#if UNDEFINED+1 == 1

(also true) so

	#if UNDEFINED
	This will not be included.
	#else
	But this will.
	#endif

If a macro is defined as 0 then it is defined!  So
	
	#define ZERO 0
	#ifdef ZERO
	This will be included.
	#endif

To turn off
	#ifdef VAX
use
	#undef VAX

after the point where VAX is defined or simpler still, just don't define it!
Does this help?
--
Denis Howe <dbh@doc.ic.ac.uk>      C-C
H558A Imperial College London     C-C-C
   +44 (71) 589 5111 x5064         N=N

gtoal@castle.ed.ac.uk (G Toal) (05/19/91)

In article <1991May16.125325.15323@doc.ic.ac.uk> mybg@doc.ic.ac.uk (M Y Ben Gershon) writes:
>
>Am I crazy, or is there a subtle bug in C release 3?  I am surprised that
>nobody has mentioned it so far, but the ANSI standard, as far as I can
>gather, states that if a preprocessor macro is undefined, it is deemed to
>have a value of 0 (in fact 0L, to be precise).  According to the latest K&R,
>(which is the ANSI version), and Harbison & Steele, a macro defined as being
>0 is identical to a macro which is undefined, as above.  However, Cv3 treats
>them differently:  If a macro is defined as:
>
>    #define VAX 0
>
>and we then do:
>
>    #ifdef VAX
>    #error VAX is defined!
>    #endif
>
>the error message will be displayed.  By the way, who noticed the section on

Which reminds me of a general point when porting programs - for progs
with lots of target machines, some authors tend to use #if rather than
#ifdef so that they cal say things like '#if VAX || (UNIX && BSD42)'
-- so they have a header file where *all* the possible symbols are
defined - most as 0, one as 1.  Now a modern ANSI C programmer
comes along to port it, and accidentally puts in a '#ifdef VAX' (or
more likely '#ifndef VAX') and is suprised when the wrong thing happens.
It is *very* hard not to accidentally use ifdef in these situations - the
supplied '#if' style being a bit non-obvious.

Nowadays I use '#if defined(VAX) || defined(BSD42)'
almost exclusively. Much safer.  But of course, old compilers will
treat expressions with 'defined()' in them as an error and assume
the expression is FALSE. ho hum.

Graham