我正在尝试在 C 中创建“单行注释”宏,根据一些全局宏定义,这有条件地用于注释掉代码行。这与this article中表达的观点相同。
尝试使用此代码的许多排列,我不断收到编译器的错误消息。
例如,直接关注该页面的代码示例:
#define COMMENT SLASH(/)
#define SLASH(s) /##s
#define DEBUG_ONLY COMMENT
DEBUG_ONLY a = b; // <-- line #83
GCC给出以下错误:
prog.c:83:1:错误:粘贴“/”和“/”没有给出有效的预处理标记
prog.c:83:错误:'/'标记之前的预期表达式
如前所述,我玩过这个主题并尝试了很多变化,但都没有给出类似的诊断。
我做错了什么,为什么文章中的代码编写得不好?
答案 0 :(得分:17)
它不起作用,因为语言规范不允许它。实际上,在宏替换之前发生了注释删除。删除注释后,//
不是有效令牌(如错误消息所示)。它不能通过宏替换生成,它不再意味着“评论”。
这是标准中的“翻译阶段”。章节编号有所不同,但C89,C99和C11都在第3阶段定义:
每个评论都被一个空格字符替换。
然后在第4阶段:
扩展宏调用
答案 1 :(得分:9)
调试宏:
#define DEBUG(x) x
可以在生产中关闭:
#define DEBUG(x)
或IIRC #undef
(抱歉,我的C生锈了。)
答案 2 :(得分:7)
为什么不简单地使用例如。
#ifdef DEBUG
a = b;
#endif /* DEBUG */
减少麻烦,同样可读。
答案 3 :(得分:1)
我在应用程序中使用了#define cout(x) //cout<<x;
。您可能需要像
#ifdef DEBUG
#define cout(x) cout<<x;
#else
#define cout(x)
并将其用作
cout(arg0<<arg1<<arg2);
在这里,您无需注释行,因此无需单独的行即可避免打印。 此外,无论何时需要无条件打印,都可以使用cout。
cout("Print this when debugging");
cout<<"Always print this";
答案 4 :(得分:0)
使用#define
宏,您无法注释整行每个,但您可以将所有内容注释掉,直到下一个分号。我发现这种方法效果很好。
#define LOG_LVL 111100011
// 987654321
#if(LOG_LVL%10 >= 1 )
#define LOG1 if(1)
#else
#define LOG1 if(0)
#endif//End LOG1 if-block
#if(LOG_LVL%1000 >= 100)
#define LOG3 if(1)
#else
#define LOG3 if(0)
#endif//End LOG3 if-block
只要你小心分号,这应该可以正常工作。默认情况下,非支撑if
语句仅执行以下行。
执行此类日志记录的另一个好处是,您可以微调所需的日志记录级别。在此示例中,LOG1
已启用且LOG3
已禁用。如果我希望我的日志记录更加详细,我可以快速更改LOG_LVL 111100011
以使其1
(或更高)位于 3 位,以便LOG3
启用。