2010-09-28 91 views
6

我有以下宏:C预处理与if语句

#define IF_TRACE_ENABLED(level) if (IsTraceEnabled(level)) 

用户代码应该如下:

IF_TRACE_ENABLED(LEVEL1) 
{ 
    ... some very smart code 
} 

这里花括号强调 - 我要防止“如果”从宏 “吃” 其他代码:

if (...) 
    IF_TRACE_ENABLED(LEVEL1) 
     printf(....); 
else 
    bla bla bla 

在这个例子中IF_TRACE_ENABLED “吃” else块。

有没有办法强制用户代码不编译没有卷闸或有其他来定义宏来实现安全?

+2

我没有看到这个宏给你的裸if语句。 – JeremyP 2010-09-28 10:29:03

+2

忘掉这个例子。你可能会遇到一个复杂的情况,那就是你不想每次都重复一遍。 – 2010-09-28 11:08:37

+0

@JeremyP:在这个简单的例子中,没有太多实用的宏,但是正如Nathan指出的那样,在调试宏中可能会有更多的复杂性和/或基于构建配置的宏有多种变化例如,总是评估为“false”的版本版本,以便跟踪字符串从可执行文件中除去)。 – 2010-09-28 14:37:09

回答

11

这并不强制宏的用户使用大括号,但它会防止不小心被吃掉的else条款:

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

一个侧面说明:在printf()左右括号中的第二个例子该问题不会解决问题 - 与bla bla bla关联的else仍将绑定到宏中的if语句。

+1

尝试并未能想出一个办法,这可能会适得其反。 +1 – 2010-09-28 08:46:38

+0

“if”块的内容在哪里通过?在else块中的 – dimba 2010-09-28 09:42:58

+1

;很好的答案! – 2010-09-28 10:08:46

0

这应该工作,但你必须在通过该if块的内容作为参数传递给宏还有:

#define IF_TRACE_ENABLED(level,content) { if (IsTraceEnabled(level)) {content} } 
+0

这不是必需的printf(...)。这可以是只有在宏条件为真时才应该评估的任何代码。 – dimba 2010-09-28 08:02:37

+0

您应该在内容周围添加一个块。 – 2010-09-28 08:03:41

+0

@Ronny - 这是我想要强制执行的用户,所以如果他忘记这样做,汇编将失败 – dimba 2010-09-28 08:19:00

2

你可以试试这个:

#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括起来有什么问题。

+0

我在解决方案中唯一不喜欢的是stat和stop宏之间的缩进 - 编辑器不会缩进它。 – dimba 2010-09-28 08:05:02

+1

是不是可以简单地使用大括号,而不做&while? – 2010-09-28 08:07:23

+0

@ptmato - @crypto说有什么。 do/while用于在宏前面看起来像普通函数,因为他强制使用“;”到底。所以“;”在宏观的结尾是多余的。 任何我们不会“;”的方式因为这个宏看起来不像函数调用 – dimba 2010-09-28 08:22:02