当前位置:  开发笔记 > 编程语言 > 正文

C预处理器是否首先删除注释或扩展宏?

如何解决《C预处理器是否首先删除注释或扩展宏?》经验,为你挑选了3个好方法。

考虑这个(可怕的,可怕的,没有好的,非常糟糕的)代码结构:

#define foo(x) // commented out debugging code

// Misformatted to not obscure the point
if (a)
foo(a);
bar(a);

我已经看到两个编译器的预处理器在这段代码上生成不同的结果:

if (a)
bar(a);

if (a)
;
bar(a);

显然,对于可移植的代码库来说这是一件坏事.

我的问题:预处理器应该用这个做什么?首先是Elide评论,还是先扩展宏?



1> Reed Copsey..:

遗憾的是,最初的ANSI C规范明确排除了第4节中的任何预处理器功能("此规范仅描述了C语言.它没有为库或预处理器提供任何规定.").

但是,C99规范处理了这种明显性.在"转换阶段"中,注释将替换为单个空格,该空间在预处理指令解析之前发生.(详见第6.10节).

VC++和GNU C编译器都遵循这个范例 - 如果它们更老,其他编译器可能不兼容,但如果它符合C99,那么你应该是安全的.


抱歉,您链接的是__not__ ANSI C规范; 实际规范描述了2.1.1.2节中的翻译阶段; 我不久前发布了这些阶段的概述:http://stackoverflow.com/questions/1476892/poster-with-the-8-phases-of-translation-in-the-c-language/1479972#1479972

2> Michael Burr..:

如在C99标准中的翻译阶段的复制粘贴描述中所述,在翻译阶段3中发生删除注释(它们被单个空格替换),同时处理预处理指令并且在阶段4中扩展宏.

在C90标准(我只有硬拷贝,所以没有copy-n-paste)这两个阶段以相同的顺序出现,尽管翻译阶段的描述在一些细节上与C99标准略有不同 - 事实在处理预处理指令并扩展宏之前,注释将被删除并替换为单个空白字符.

同样,C++标准有两个阶段以相同的顺序发生.

至于如何//处理'评论,C99标准说(6.4.9/2):

除了字符常量,字符串文字或注释之外,字符//引入的注释包括所有多字节字符,但不包括下一个换行符.

C++标准说(2.7):

字符//开始一个注释,它以下一个换行符结束.

所以你的第一个例子显然是该翻译器的一个错误 - 当宏扩展时应该保留的' ;'字符- 注释字符不应该是宏的'内容'的一部分.foo(a)foo()the foo()

但是,由于您遇到了错误的翻译器,您可能希望将宏定义更改为:

#define foo(x) /* junk */

解决这个问题.

然而(我在这里偏离主题...),因为在处理注释之前发生了行拼接(在新行之前的反斜杠),你可能遇到类似这样讨厌的代码:

#define evil( x) printf( "hello "); // hi there, \
                 printf( "%s\n", x); // you!



int main( int argc, char** argv)
{
    evil( "bastard");

    return 0;
}

写这篇文章的人可能会感到惊讶.

或者甚至更好,尝试以下,由喜欢盒式评论的人(当然不是我!)写的:

int main( int argc, char** argv)
{
                            //----------------/
    printf( "hello ");      // Hey, what the??/
    printf( "%s\n", "you"); // heck??         /
                            //----------------/
    return 0;
}

根据你的编译器是否默认处理三字符(编译器应该是这样,但由于三元组几乎让每个运行它们的人感到惊讶,一些编译器决定默认关闭它们),你可能会也可能不会得到你想要的行为 -当然,无论是什么行为.


问题的关键是“垃圾”是实际的代码,在不用于调试时被注释掉。

3> Jim Lewis..:

根据MSDN,在标记化阶段用单个空格替换注释,这在宏扩展的预处理阶段之前发生.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有