C:对预处理器宏感到困惑

时间:2014-10-11 23:11:47

标签: c macros c-preprocessor

我添加了一堆" debug(x)"使用头文件中的预处理宏对我的代码进行语句。我还实现了一个切换(通过头文件中的#ifdef / #else结构),可以让我关闭调试语句。我无法让这个切换工作,我希望有人能找出原因。

我没有重新发布实际代码(冗长),而是包含一个说明性示例(编译时)。

这是我们的.h文件。它由一个名为"超人"的函数的宏组成。当且仅当我们的.c文件中没有定义KRYPTONITE时,才应打印该语句。

test.h:

#ifndef __test_h__
#define __test_h__

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

#endif

正如您在下面的案例中所见,添加" #define KRYPTONITE 1"声明到我们的.c文件的开头不会切断"超人"功能(下面的案例2)。但是,如果我们在编译指令中通过标志定义KRYPTONITE,我们就会成功切换(案例3)。

我需要做些什么才能切断超人"功能通过" #define" .c文件中的语句?


案例1:.c文件中没有定义KRYPTONITE(它被注释掉了)。正如所料,声明打印。 (.c文件和输出如下。)

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;
}

输出:

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

Superman, are you here?
I'm here

dchaudh@dchaudhUbuntu:~/SO$

案例2:KRYPTONITE在我们的.c文件中定义,但语句打印。

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;
}

输出:

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

Superman, are you here?
I'm here

dchaudh@dchaudhUbuntu:~/SO$

案例3:KRYPTONITE未在我们的.c文件中定义,但我们在编译时通过标志定义它。在这种情况下,超人功能成功切换。

输出:

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

Superman, are you here?

dchaudh@dchaudhUbuntu:~/SO$

1 个答案:

答案 0 :(得分:2)

与C编译器一样,预处理器从上到下扫描文件。这意味着必须在使用之前定义宏

因此,要解决您的问题,请将#define放在#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;
}