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