Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 带if语句的C预处理器_Macros_C Preprocessor - Fatal编程技术网

Macros 带if语句的C预处理器

Macros 带if语句的C预处理器,macros,c-preprocessor,Macros,C Preprocessor,我有以下宏: #define IF_TRACE_ENABLED(level) if (IsTraceEnabled(level)) 用户代码应如下所示: IF_TRACE_ENABLED(LEVEL1) { ... some very smart code } 这里强调的是花括号-我想防止宏中的“if”变成“eat”其他代码: if (...) IF_TRACE_ENABLED(LEVEL1) printf(....); else bla bla bla

我有以下宏:

#define IF_TRACE_ENABLED(level)  if (IsTraceEnabled(level))
用户代码应如下所示:

IF_TRACE_ENABLED(LEVEL1)
{
    ... some very smart code
}
这里强调的是花括号-我想防止宏中的“if”变成“eat”其他代码:

if (...)
   IF_TRACE_ENABLED(LEVEL1)
      printf(....);
else
   bla bla bla
在本例中
如果启用了跟踪
“eats”else块


有没有办法强制用户代码在没有卷曲制动器的情况下不编译,或者有其他方法来定义宏以实现安全性?

这应该是可行的,但您也可以将if块的内容作为参数传递给宏:

#define IF_TRACE_ENABLED(level,content)  { if (IsTraceEnabled(level)) {content} }
你可以试试这个:

#define IF_TRACE_ENABLED(level) do { if(IsTraceEnabled(level)) {
#define END_TRACE_ENABLED } } while(0);
我不认为有任何方法可以仅从宏的开头行“强制”好的语法。您需要使用两个

编辑

我在宏中添加了一对额外的大括号,以避免所有歧义

作为对注释的回应,此宏的使用方式如下:

IF_TRACE_ENABLED(LEVEL1)
    printf("Trace\n");
END_TRACE_ENABLED

不是作为声明。作为记录,我认为这是对预处理器的滥用,任何人都不应该这样做。如果需要,用
#ifdef DEBUG
括起来写出来有什么错。

这不会强制宏用户使用大括号,但可以防止无意中吃掉
else
子句:

#define IF_TRACE_ENABLED(level)  if (!IsTraceEnabled(level)) {} else 


旁注:在问题的第二个示例中,
printf()
周围的大括号不会解决问题-与
bla-bla-bla
关联的
else
仍将绑定到宏中的
if
语句。

这不是printf(…)所必需的。这可能是任何只有在宏条件为真时才应该计算的代码。您应该在内容周围添加一个块。@Ronny-这是我想要强制用户执行的,所以如果他忘记执行,编译会失败,将内容传递给宏可能会很复杂,并会影响用户-我们需要小心内容中的逗号,不要将其解释为宏参数分隔符,如果我想让注释行成为注释的一部分,该怎么办。@dimba这样做不会失败。解决方案中我唯一不喜欢的是stat宏和stop宏之间的块缩进-你的编辑器不会缩进它。如果没有do&while,就不可能简单地使用大括号吗?@ptmato-这是@crypto说的。do/while用于使宏看起来像正常函数,因此他最终强制使用“;”。所以宏末尾的“;”是多余的。无论如何,我们不“;”因为宏看起来不像函数call@dimba,这并不意味着要在结尾使用分号。请参阅编辑。@crypto,可能是。我只是觉得这样做不太可能出现一个不起作用的极端情况。试图找到一种方法但失败可能会适得其反+1其中是else块中通过“如果”块的内容;回答得好@dimba:测试已被反转,因此块的内容由
else
@Chris Lutz执行:如果用户决定需要一个else,即如果他们想要
if_TRACE_ENABLED(level)。。。else{…}
我看不出该宏在裸if语句上给出了什么。忘记这个例子吧。如果你不想每次都重复,你可能会遇到一个复杂的情况。@JeremyP:对于这个简单的例子,使用宏没有多大用处,但正如Nathan所指出的,调试宏可能更复杂,和/或基于构建配置的宏可能有多种变体(例如,发布版本的计算结果总是
false
,因此跟踪字符串从可执行文件中剥离)。那么,为什么不为条件设置一个宏,即if中的布尔表达式呢?@JeremyP:有很多方法可以得到类似的结果,而将宏用于条件是我喜欢的方法之一(但你可能会惊讶于有多少人不喜欢)。我的博客上有一篇文章:。你是对的,问题中的宏可能没有很多理由以问题中的简单形式独立存在。但是,我在野外看到过类似的宏,通常是一组调试宏中的一个,根据构建配置的不同,这些宏具有不同的定义。我认为有一种技巧来处理问题中提出的问题是有价值的。