当使用没有替换字符串的#define时会发生什么?

时间:2017-07-19 08:07:05

标签: c c-preprocessor

在尝试调试我的代码时,我用这个标记了一些printf

#if debug
    printf(...);
#endif

在文件开头,我错误地写了#define debug而不是#define debug 1

gcc抛出以下错误:

  

错误:#if没有表达

现在我有两个选择:

  1. 将定义更改为#define debug 1
  2. 将if更改为#ifdef debug
  3. 我知道,在看到#define debug 1后,PP会将我的代码中的每个debug替换为1,这就是为什么代码中的#if debug没有&#39} ; t work - 编译器看不到表达式......

    我的问题是,当我使用#ifdef debug时会发生什么?我认为debug保存在某处并检查,但在哪里以及如何?

2 个答案:

答案 0 :(得分:4)

实际上非常简单:#define debug debug定义为空。它仍然是定义的。空宏与不存在的宏不同。 #undef debug会移除宏。

#ifdef并不关心价值。它只检查宏是否被定义为任何东西。如果您不关心该值,请始终使用#ifdef

答案 1 :(得分:2)

#define预处理指令的相关语法在§6.10 ¶1(C11标准草案)中详细说明:

  

#define 标识符替换列表换行
  ...
   replacement-list:pp-tokens opt

#define指令的语义可在§6.10.3中找到:

  

表单

的预处理指令      

#define 标识符替换列表换行

     

定义一个类似对象的宏,它会导致每个后续实例   要替换列表的宏名称   预处理构成指令其余部分的令牌。   然后重新扫描替换列表以获取更多宏名称   如下所示。

请注意,替换列表可选由预处理标记组成,因此可能为空。所以,考虑footnoted example from the Standard

#define EMPTY

根据§6.10.3 ¶7

  

紧跟在 define 之后的标识符称为宏   名称的。宏名称有一个名称空间。

宏名称EMPTY已定义,并存在于宏名称的名称空间中。 EMPTY的每个后续实例都将被替换为无预处理令牌。