[comp.lang.c] Using a define that hasn't been #defined

jls@hsv3.UUCP (James Seidman) (10/03/90)

Recently I've run into a couple of hard-to-track bugs because I have
a section of conditionally compiled code using a symbol which hasn't
been defined.  For example, take the trivial case of this "program"

-------

#define XYZZY 1

main() {
#if XYZZU
	printf("xyzzy\n");
#else
	printf("plugh\n");
#endif
}

------

Now, obviously that XYZZU was supposed to be an XYZZY, and I wanted to
conditionally compile the first piece of code, not the second.  But when
I compile this, it doesn't even give me a friendly warning, and just
assumes XYZZU is 0.  (Which, I understand, is in accordance with ANSI-
defined behavior.)

Now, my question is how other people avoid these same kinds of idiotic
mistakes?  Even if I put in "#if !defined(XYZZY)..." type things for
every define, it still wouldn't catch all typos.  There should be some
way to avoid this idiotic kind of error...
-- 
Jim Seidman (Drax), the accidental engineer.
"There's a certain freedom to being completely screwed." - The Freshman
UUCP: ames!vsi1!headland!jls
ARPA: jls%headland.UUCP@ames.nasa.arc.gov

gordon@osiris.cso.uiuc.edu (John Gordon) (10/03/90)

	In fact, there is a very good way to avoid this kind of error: use the
compiler directives #ifdef and #ifndef.  These check to see if a given 
identifier has or has not been #define'd.

	Example:

	#ifdef MSDOS
	do_dos_specific_stuff();
	...
	...

	Hope it helps.


---
John Gordon
Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
          gordon@cerl.cecer.army.mil       #include <clever_saying.h>
GEnie:    j.gordon14                  

karl@haddock.ima.isc.com (Karl Heuer) (10/03/90)

In article <5101@hsv3.UUCP> jls@headland.UUCP (James Seidman) writes:
>#define XYZZY 1
>...
>#if XYZZU

I've always wished that the preprocessor had used modern language-design
principles and made undefined variables illegal rather than synonyms for
zero.  Unfortunately there was a large body of code that depended on the
sloppiness, so now we're stuck with it.

The best we can hope for is to get compiler vendors to provide an option to
warn whenever an undefined symbol is used in a preprocessor conditional
(other than as the operand of defined(), of course).  Then the next step
is to get software vendors to use "#if _S_UNIX" instead of "#ifdef _S_UNIX"
to test the compilation environment--that way, it becomes possible to
distinguish "symbol not set because this isn't UNIX" from "symbol not set
because that's not the name I use to flag what you're trying to test".

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint

dts@quad.sialis.mn.org (David T. Sandberg) (10/03/90)

In article <1990Oct3.022132.9245@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
>	In fact, there is a very good way to avoid this kind of error: use the
>compiler directives #ifdef and #ifndef.  These check to see if a given 
>identifier has or has not been #define'd.

I'm not the one who asked about this in the first place, but I really
don't see how that would be expected to alleviate the situation.  You
see, I recently encountered a bug of a similar character (heh), as
follows:

#define SYSV

{
    ...
#ifdef SYSY
    ...
#endif
    ...
}

In this situation, whether you use #if or #ifdef doesn't make any
difference.  To exasperate the situation, I was using a terminal
upon which capital 'V's and 'Y's look even more similar than normal,
and the problem resulting from the #ifdef-ed code's absence only
manifested itself much later, in another module entirely separate
from the one where the bug was hiding.

That one took days, and large chunks of my hair, to find.  B-(

I suppose that, if one is very concerned about this and is using
an ANSI-compliant preprocessor, one could do something like this:

#include <stdio.h>

#define SYSV	1
#define DOS	2
#define	OSTYPE	SYSV

main()
{
#if OSTYPE == SYSV
	printf( "This is the System V-specific code.\n" );
#elif OSTYPE == DOS
	printf( "This is the System V-specific code.\n" );
#else
#error OSTYPE undefined or mistyped
#endif
}

-- 
 \\         David Sandberg          \     ,=,       ,=,           \\
 //     dts@quad.sialis.mn.org      /     | |uadric '=,ystems     //
 \\  uunet!rosevax!sialis!quad!dts  \     '=\       `='           \\

henry@zoo.toronto.edu (Henry Spencer) (10/04/90)

In article <5101@hsv3.UUCP> jls@headland.UUCP (James Seidman) writes:
>Recently I've run into a couple of hard-to-track bugs because I have
>a section of conditionally compiled code using a symbol which hasn't
>been defined...
>Now, my question is how other people avoid these same kinds of idiotic
>mistakes?  Even if I put in "#if !defined(XYZZY)..." type things for
>every define, it still wouldn't catch all typos.  There should be some
>way to avoid this idiotic kind of error...

Two rules that can help with this and related problems are:

1. When enumerating values for a code, start at 1, not 0.

2. Make sure that if the user hasn't specified a choice (e.g. hasn't
	defined one of several symbols tested with #ifdef, or hasn't
	given a non-zero value to something tested with #if) that
	the result is a complaint, not a default choice.
-- 
Imagine life with OS/360 the standard  | Henry Spencer at U of Toronto Zoology
operating system.  Now think about X.  |  henry@zoo.toronto.edu   utzoo!henry