#if定义MACRO是否相当于#ifdef MACRO?

时间:2016-09-02 10:18:43

标签: c macros c-preprocessor

我的代码我希望有两种模式,调试详细。我在头文件中将它们定义为

#define verbose TRUE
#define debug TRUE

到目前为止,在我的代码中,我刚刚使用

#if(debug)
  //code
#endif

但使用

更合适
#ifdef debug
  // code
#endif

我读过有关预处理器宏的内容但当时没有意义。所以,我有疑问,#if defined MACRO是否等同于#ifdef MACRO?哪个更好地启用/禁用特定代码段?

5 个答案:

答案 0 :(得分:18)

#ifdef MACRO
#if defined (MACRO)

会做同样的事情。但是,定义的(MACRO)只是一个在#if内部计算为0或1的表达式,它可以与其他表达式组合。例如

#if defined (MACRO) && ! defined (MACRO2)
    // Do this
#else
    // Do that
#endif

尝试使用#ifdef - 除非你的代码变得非常笨拙,否则你不能这样做。

答案 1 :(得分:7)

#if defined(MACRO)#ifdef MACRO相同,但更长。另一方面,它允许使用||&&添加额外条件。

#if MACRO#ifdef MACRO类似,但不是100%。如果MACRO0,那么#if MACRO将为负数 - 需要定义MACRO而不是0#ifdef仅检查是否定义了它是否没有值(#define MACRO)。

现在使用#if并启用/禁用值为1或0的定义是现代的:

#define FLAG_X 1 // or 0

答案 2 :(得分:7)

不,它们根本不相同。如果#if MACRO求值为非零,则编译MACRO分支。另一方面,如果#ifdef MACRO 已定义,则会编译MACRO分支,无论其评估结果如何。所以

#include <stdio.h>

#define VAR_SET_TO_TRUE 1
#define VAR_SET_TO_FALSE 0

int main()
{

#if VAR_SET_TO_TRUE
    printf("#if VAR_SET_TO_TRUE\n");
#endif

#if VAR_SET_TO_FALSE
    printf("#if VAR_SET_TO_FALSE\n");
#endif

#if VAR_UNSET
    printf("#if VAR_UNSET\n");
#endif



#ifdef VAR_SET_TO_TRUE
    printf("#ifdef VAR_SET_TO_TRUE\n");
#endif

#ifdef VAR_SET_TO_FALSE
    printf("#ifdef VAR_SET_TO_FALSE\n");
#endif

#ifdef VAR_UNSET
    printf("#ifdef VAR_UNSET\n");
#endif

}

将输出

#if VAR_SET_TO_TRUE
#ifdef VAR_SET_TO_TRUE
#ifdef VAR_SET_TO_FALSE

请注意,行printf("#ifdef VAR_SET_TO_FALSE\n");已编译,而行printf("#if VAR_SET_TO_FALSE\n");则未编译。第一个是编译的,因为VAR_SET_TO_FALSE 已定义,即使其值为false

答案 3 :(得分:3)

如果我正确地阅读了您的问题,标题会产生误导,那应该是

Is #if MACRO equivalent to #ifdef MACRO?

它们不是等价的,但它们可以(通常是)用于指定打开或关闭的二进制模式。在我看来,选择是个人偏好的问题。

您正在使用第一个选项,并且

#define verbose true

#define verbose false

然后使用

检查模式
#if verbose

#if !verbose

实际上,我建议您使用TRUE或1而不是true,使用FALSE或0而不是false,因为true和false,是(或可以是)C / C ++值且预处理器没有&#39;可以访问C / C ++值。

无论如何,指定二进制模式的另一种常用方法是定义标志或保持未定义,在这种情况下你可以拥有

#define verbose any thing (including nothing) goes here

或遗漏#define。

然后你可以用

测试是否定义了标志
#ifdef verbose

或其等价物

#if defined(verbose)

注意:在这种情况下,您不会测试您只需要测试它是否已定义的标志值。

如果更方便,您还可以使用

测试标志是否未定义
#ifndef verbose

或其等价物

#if !defined(verbose)

答案 4 :(得分:2)

如果我们绞尽脑汁,我们可以想出一个不同之处。但它是模糊的并且涉及未定义的行为,因此如果我们关心的是代码是否严格符合ISO C,则无关紧要。

如果先前处理了select * from table where columnA like '%02%' and columnA like '%03%' columnA like '%02%' and columnA like '%08%' and columnA like '%31%' and columnA like '%99%' and columnA like '%99%' 宏,#if defined ...表单的行为会有所不同。在ISO C99标准中,它是针对#define defined ...#if指令编写的:

  

在评估之前,将替换将成为控制常量表达式的预处理标记列表中的宏调用(由定义的一元运算符修改的宏名称除外),就像在普通文本中一样。

不要求#elif一元运算符被识别并保护不被视为宏;它只是成为......表达式&#34;的预处理标记之一。 defined运算符在此阶段仅在保护其参数不受扩展的情况下被识别。

如果简单地允许defined作为宏的定义,并且define的出现随后被替换(包括在defined预处理指令的参数中),从而干扰{ {1}},但不影响#if

自从C99以来,这个语言区域可能已经收紧了。