10

我正在尝试在C中创建一个“单行注释”宏,根据一些全局宏定义,它有条件地用于注释掉代码行。这与本文所表达的想法相同。

尝试了此代码的许多排列,我不断收到来自编译器的错误消息。

例如,直接遵循该页面中的代码示例:

#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:错误:“/”标记之前的预期表达式

如前所述,我使用该主题并尝试了许多变体,但都未能给出类似的诊断。

我做错了什么,为什么文章中的代码编译不好?

4

5 回答 5

19

它不起作用,因为语言规范不允许这样做。实际上,注释删除发生宏替换之前。删除评论后,//它就不是有效的令牌(如错误消息所述)。不能通过宏替换生成,不再是“注释”的意思。

这是标准中的“翻译阶段”。部分编号不同,但所有 C89、C99 和 C11 都在阶段 3 中定义:

每个注释被一个空格字符替换。

然后在第 4 阶段:

宏调用被扩展

于 2013-03-21T11:07:57.693 回答
9

调试宏:

#define DEBUG(x) x

可以在生产中关闭,如下所示:

#define DEBUG(x)

或 IIRC #undef(对不起,我的 C 生锈了)。

于 2013-03-21T11:00:38.720 回答
7

为什么不简单地使用例如

#ifdef DEBUG
a = b;
#endif  /* DEBUG */

更少的麻烦,同样可读。

于 2013-03-21T10:58:04.797 回答
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";
于 2020-05-09T11:57:14.097 回答
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 11110001131位数(或更高),以便启用。LOG3

于 2013-12-24T03:04:44.967 回答