[comp.lang.c] Conditional #if preprocessor expressions

noren@dinl.uucp (Charles Noren) (04/17/91)

This is my day to ask stupid questions....

I have defined a macro symbol, INCL to be:

  #define INCL apple

I then use INCL in the following expressions:

  #if INCL == apple
  #include "apple.h"
  #endif

  #if INCL == orange
  #include "orange.h"
  #endif

My expectation is that only the include file "apple.h"
is included.  However, the include file "orange.h" is
included as well.  Why is this? 
(I know there must be an obvious answer...)
BTW, some examples in nihcl use this construct.  See
ex11-1.c under the ex directory.

My environment:

 o  Sun Spac station 2.
 o  SunOS 4.1.1
 o  Saber C++ 1.0
 o  also compiled under the default Sun cc.

Sample program:

======main.c==================================
/*
 * File: main.c
 *
 */

#define INCL apple

#if INCL == apple
#include "apple.h"
#endif

#if INCL == orange
#include "orange.h"
#endif

#include <stdio.h>

char* myString = FRUIT;

main()
{
    printf("myString = [%s].\n", myString);
}
==============================================

======apple.h=================================
/* File: apple.h  */

#define FRUIT "apple"

==============================================

======orange.h================================
/* File: orange.h  */

#define FRUIT "orange"

==============================================


Thanks,


-- 
Chuck Noren
NET:     dinl!noren@ncar.ucar.edu
US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260,
         Denver, CO 80201-1260
Phone:   (303) 977-1646

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (04/18/91)

In article <1849@dinl.mmc.UUCP>, noren@dinl.uucp (Charles Noren) writes:
>   #define INCL apple

>   #if INCL == apple
>   #include "apple.h"
>   #endif

>   #if INCL == orange
>   #include "orange.h"
>   #endif

It doesn't work.  The reason is that, as stated in C manuals and textbooks,
the operand of an #if directive is an *integer* constant expressions, and
identifiers which are not defined as macros are in effect replaced by 0.
Hence
	#if INCL == orange
turns into
	#if apple == orange
which behaves like
	#if 0 == 0

The answer is to make sure that apple and orange _are_ defined:
	#define apple 1
	#define orange 2
some time before the first use of apple or orange.

-- 
Bad things happen periodically, and they're going to happen to somebody.
Why not you?					-- John Allen Paulos.

steve@taumet.com (Stephen Clamage) (04/18/91)

noren@dinl.uucp (Charles Noren) writes:

>I have defined a macro symbol, INCL to be:
>  #define INCL apple
>I then use INCL in the following expressions:

>  #if INCL == apple
>  #include "apple.h"
>  #endif

>  #if INCL == orange
>  #include "orange.h"
>  #endif

>My expectation is that only the include file "apple.h"
>is included.  However, the include file "orange.h" is
>included as well.  Why is this? 

The preprocessor does not do string comparison, just integer arithmetic.
The preprocessor rule is that if a name has not been #defined, its
value is zero.  So INCL is defined to be apple, which apparently has
not been #defined.  The value of apple is then 0, and so the value of
INCL is 0, and the two are equal; "apple.h" is then #included.

Next, INCL is compared to orange, which has not been #defined, so its
value is 0, the same as the value of INCL; "orange.h" is then #included.

What you want is something more along the lines of

	#define APPLE	/* or ORANGE, or whatever */

	#ifdef APPLE
	#include "apple.h"
	#endif

	#ifdef ORANGE
	#include "orange.h"
	#endif
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

noren@dinl.uucp (Charles Noren) (04/19/91)

In article <1849@dinl.mmc.UUCP> noren@dinl.UUCP (Charles Noren) writes:
>This is my day to ask stupid questions....
>(I know there must be an obvious answer...)

Thanks to the MANY who have responded to this.  There is at least one
good posting so I don't need to go over the solution.  Thanks for the
kindness shown for such a simple (yes stupid) question.


-- 
Chuck Noren
NET:     dinl!noren@ncar.ucar.edu
US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260,
         Denver, CO 80201-1260
Phone:   (303) 977-1646