我的代码我希望有两种模式,调试和详细。我在头文件中将它们定义为
#define verbose TRUE
#define debug TRUE
到目前为止,在我的代码中,我刚刚使用
#if(debug)
//code
#endif
但使用
更合适#ifdef debug
// code
#endif
我读过有关预处理器宏的内容但当时没有意义。所以,我有疑问,#if defined MACRO
是否等同于#ifdef MACRO
?哪个更好地启用/禁用特定代码段?
答案 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%。如果MACRO
为0
,那么#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以来,这个语言区域可能已经收紧了。