iceman
iceman

Reputation: 2130

C: Confused about preprocessor macros

I've added a bunch of "debug(x)" statements to my code using preprocessing macros in a header file. I've also implemented a toggle (via an #ifdef / #else structure in the header file) that lets me turn off the debug statements. I'm having trouble getting this toggle to work and am hoping someone can figure out the reason.

Rather than re-posting the actual code (which is lengthy), I'm including an illustrative example (which does compile).

Here's our .h file. It consists of a macro for a function named "superman". The statement should print if and only if KRYPTONITE is not defined in our .c file.

test.h:

#ifndef __test_h__
#define __test_h__

#ifdef KRYPTONITE
#define superman(...)
#else
#define superman(xs) printf("%s\n\n",xs)
#endif

#endif

As you can see in the cases below, adding a "#define KRYPTONITE 1" statement to the beginning of our .c file does not toggle off the "superman" function (Case 2 below). However, we do successfully toggle off if we define KRYPTONITE via a flag in our compile instruction (Case 3).

What else do I need to do in order to toggle off the "superman" function via a "#define" statement in the .c file?


Case 1: KRYPTONITE not defined in the .c file (it's commented out). As expected, the statement prints. (The .c file and output is below.)

test1.c:

#include <stdio.h>
#include "test.h"
//#define KRYPTONITE

int main (int argc, char *argv[])
{
  printf("\nSuperman, are you here?\n\n");
  superman("I'm here");
  return 0;
}

Output:

dchaudh@dchaudhUbuntu:~/SO$ gcc test1.c -o test1
dchaudh@dchaudhUbuntu:~/SO$ ./test1

Superman, are you here?
I'm here

dchaudh@dchaudhUbuntu:~/SO$

Case 2: KRYPTONITE is defined in our .c file, yet the statement prints.

test2.c:

#include <stdio.h>
#include "test.h"

#define KRYPTONITE

int main (int argc, char *argv[])
{
  printf("\nSuperman, are you here?\n\n");
  superman("I'm here");
  return 0;
}

Output:

dchaudh@dchaudhUbuntu:~/SO$ gcc test2.c -o test2
dchaudh@dchaudhUbuntu:~/SO$ ./test2

Superman, are you here?
I'm here

dchaudh@dchaudhUbuntu:~/SO$

Case 3: KRYPTONITE is not defined in our .c file but we define it via a flag when compiling. In this case, the superman function is successfully toggled off.

Output:

dchaudh@dchaudhUbuntu:~/SO$ gcc -DKRYPTONITE test1.c -o test3
dchaudh@dchaudhUbuntu:~/SO$ ./test3

Superman, are you here?

dchaudh@dchaudhUbuntu:~/SO$

Upvotes: 0

Views: 158

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409442

The proeprocessor, just like the C compiler, scans files from top to bottom. That means macros must be defined before they are used.

So to solve your problem, put the #define before the #include.

#include <stdio.h>

#define KRYPTONITE

#include "test.h"

int main (int argc, char *argv[])
{
  printf("\nSuperman, are you here?\n\n");
  superman("I'm here");  // Doesn't print
  return 0;
}

Upvotes: 2

Related Questions