在 C++11 中,标准在 2.2.3 中说:
每个注释被一个空格字符替换。保留换行符。
该短语是连续的,意味着保留以换行符结尾的换行符吗?
如果 (1) 为真,那么为什么 Visual C++、gcc 和 clang 在多注释中为每一行保留空行。
这个问题很重要,因为我正在编写一个 c++ 预处理器。
在 C++11 中,标准在 2.2.3 中说:
每个注释被一个空格字符替换。保留换行符。
该短语是连续的,意味着保留以换行符结尾的换行符吗?
如果 (1) 为真,那么为什么 Visual C++、gcc 和 clang 在多注释中为每一行保留空行。
这个问题很重要,因为我正在编写一个 c++ 预处理器。
它所讨论的新行是在注释被单个空格字符替换后仍然存在的行。当在包含它的段落的更大上下文中查看片段时,这一点会更清楚。
所以特别是多行注释中的新行不会保留,也不会终止预处理指令。
AC/C++ 预处理器会去除所有注释,但是当您查看预处理器输出时,通常会将源代码行保持在相同的行号处。
这样一来,读取预处理器输出的编译器就可以为错误消息和警告打印正确的行号。
预处理器通常也会保留所有空行。
您还必须严格区分从源中删除的多行宏以及何时扩展它们。它们总是在保留所有换行符的同时被删除。它们总是被所有换行符所取代。两者都是完全独立的操作,彼此无关。
在过去,C 预处理器总是在 stdout 上产生它的输出,而 C 编译器会从 stdin 中读取它。预处理器发出内部#<N> "<FILE>"
语句,C 编译器将其解释为“行号 N 跟随”。所以理论上预处理器可以在输出中不产生空行。但在实践中,此#<N> "<FILE>"
功能仅用于#include
语句后面的行。
今天,为了提高性能,C 编译器中内置了预处理器,但如果明确要求,您仍然可以查看中间结果。
注意:另请参阅下面的好评论:该标准并未真正指定预处理器的文本输出在空格方面的外观。文本输出是特定于实现的。有很大的解释空间。定义的是至少一个空格字符必须在哪里,并且所有标记都保留在其原始行上(或用其原始行标记),以便错误消息有意义。