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

我有代码,我想有两种模式, debugverbose 。 我在我的头文件中定义它们,

#define verbose TRUE #define debug TRUE 

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

 #if(debug) //code #endif 

但使用起来更合适

 #ifdef debug // code #endif 

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

 #ifdef MACRO #if defined (MACRO) 

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

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

尝试用#ifdef做到这一点 – 你不能,除非你的代码变得非常笨拙。

#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

不,他们根本不相同。 如果MACRO评估为非零,则编译#if MACRO分支。 另一方面,如果定义#ifdef MACRO则编译#ifdef MACRO分支,无论它评估的是什么。 所以

 #include  #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");编译printf("#if VAR_SET_TO_FALSE\n"); 不是。 第一个是编译的,因为定义了 VAR_SET_TO_FALSE ,即使它的值为false

如果我正确地阅读你的问题标题是误导性的,它应该是

 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 ++值,并且预处理器无法访问C / C ++值。

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

 #define verbose any thing (including nothing) goes here 

或者省略#define。

然后你可以测试是否定义了标志

 #ifdef verbose 

或其等价物

 #if defined(verbose) 

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

如果更方便的话,你也可以测试标志是否未定义

 #ifndef verbose 

或其等价物

 #if !defined(verbose) 

如果我们绞尽脑汁,我们就能想出差异。 但它是模糊的并且涉及未定义的行为,因此如果我们关心的是代码是否严格符合ISO C则无关紧要。

如果以前处理了#define defined ...宏,则#if defined ...表单容易出现不同的行为。 在ISO C99标准中,它是针对#if#elif指令编写的:

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

不要求defined一元运算符被识别并保护不被视为宏; 它只是“预处理令牌中的一个成为……表达”。 在此阶段识别defined运算符仅用于保护其参数不受扩展的影响。

如果简单地允许define为宏的defined并且随后替换defined出现(包括在#if预处理指令的参数中),从而干扰#if defined ,同时不影响#ifdef

也许这个语言区域自C99以来就收紧了。