在C语言中,#ifndef被忽略了吗?

3

我有一段代码,只想在定义了DEBUG的情况下才记录日志。所以我想用注释字符串“//”替换标记(这里是“DEBUGLOG”)。但是如何实现呢?

    #ifndef DEBUG
     #define DEBUGLOG //
    #endif

[...] 
    DEBUGLOG        printf("Debug String"\n);
[...]

在代码中没有定义DEBUG。但是我的gcc编译了这行代码,程序本身执行了printf()函数。

为什么会这样?

我尝试将它放在括号中,像这样,但它会出现编译错误:

#ifndef DEBUG
 #define DEBUGLOG "//"
#endif

这是编译器的消息:

beispiel.c:45:10: error: expected ‘;’ before ‘printf’
 DEBUGLOG printf("Debug String"\n);
          ^

有什么提示吗?


你的编译器能输出预处理代码吗?如果可以的话,你可能会发现在预处理之前注释被剥离了,宏展开成了“空”。 - Jongware
抱歉,我不明白。“在预处理之前,注释会被剥离” - 在这个阶段它还不是注释。 然后预处理器跟随并用“//”替换字符串。 然后我有一个注释,编译器无法处理,因为第一步已经完成?奇怪... - Christian
1个回答

3
如果您查找翻译阶段,您会发现预处理器执行的阶段(第4阶段)在注释被替换为空格字符(第3阶段)之后。

第3阶段
1)源文件被分解为注释、空白字符序列(空格、水平制表符、换行符、垂直制表符和换页符)和预处理标记,它们是以下内容
...
2)每个注释都被替换为一个空格字符

第4阶段
1)执行预处理器。

所以在第3阶段中,这一行:
#define DEBUGLOG //

变成:

#define DEBUGLOG 

在第四阶段,“行:”
DEBUGLOG        printf("Debug String"\n);

变成:

printf("Debug String"\n);

我就是你的 printf 被执行的原因。

当你加上引号("//")时,这行代码就变成了:

"//"   printf("Debug String"\n);

引号("")将不会被删除。这是编译器错误。

好的,到目前为止我明白了。 但是为什么我使用“//”时会出现错误?它会变成“//”而不是//,对吧?有没有一种方法可以在不为每个调用添加#ifdef行的情况下获得我想要的结果? - Christian
@Christian:已经更新答案以包括这个方面。 - P.W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接