6

翻译阶段 2 的第二部分(N3485中的第 2.2.2 节)基本上说如果源文件不以换行符结尾,编译器应该将其视为已完成。

但是,如果我正确阅读它,它会对空源文件产生明确的例外,这些文件仍然是空的。

确切的文本(特别强调)是:

每个反斜杠字符 ( \) 的实例后面紧跟一个换行符都被删除,拼接物理源代码行以形成逻辑源代码行。只有任何物理源行上的最后一个反斜杠才有资格成为此类接头的一部分。结果,如果生成了与通用字符名称的语法匹配的字符序列,则行为未定义。如果源文件不为空且不以换行符结尾,或者在任何此类拼接发生之前以换行符结尾且紧接在反斜杠字符之前,则应将其视为附加的 new-行字符被附加到文件中。

我无法弄清楚源文件是否为空或仅包含换行符会产生影响的任何情况。

我希望有人可以阐明这一要求背后的原因。

4

5 回答 5

5

这是为了特别支持 1994 年国际混淆 C 代码竞赛中“最严重的规则滥用”类别的获奖作品:世界上最小的自我复制程序。保证。

于 2013-02-20T00:14:47.923 回答
2

我认为这个想法是源文件通常由零行或多行组成,每行由一系列非换行符组成,后跟换行符。任何不满足该要求的源文件都需要特殊处理(因此您不会从两个不同的源文件中获得由文本组成的行)。

一个空的 C++ 源文件不是特别有用,但禁止它是没有意义的。引用的子句不是关于区分空文件和仅包含一个换行符的文件(它们之间应该没有真正的区别)。

于 2013-02-20T00:15:12.293 回答
2

我想这意味着每一行都以 \n 结尾,而空文件没有行

于 2013-02-20T00:34:14.053 回答
1

预处理器可用于构建程序源之外的东西,并且空行可能很重要——例如,它通常用于分隔文本中的段落。

于 2013-02-20T00:10:16.963 回答
0

“如果源文件不为空且不以换行符结尾,或者在任何此类拼接发生之前以换行符结尾且紧接反斜杠字符结尾,则应将其视为附加新的-line 字符被附加到文件中。”

翻译阶段 2 的第二部分(N3485 中的第 2.2.2 节)基本上说如果源文件不以换行符结尾,编译器应该将其视为已完成。

否 - 它表示如果文件“不为空”并且不以换行符结尾,则添加换行符

但是,如果我正确阅读它,它会对空源文件产生明确的例外,这些文件仍然是空的。

同意。

我无法弄清楚源文件是否为空或仅包含换行符会产生影响的任何情况。我希望有人可以阐明这一要求背后的原因。

考虑一个名为“header.h”的头文件,最后一行如下所示,没有尾随换行符

#endif  // #ifndef INCLUDED_HEADER_H

说 another.cc 包括它如下:

#include "header.h"
#include "another.h"

解析 another.cc 时,header.h 中的文本将替换指定包含它的行。天真地做,这将导致:

#endif  // #ifndef INCLUDED_HEADER_H#include "another.h"

显然,编译器将无法对 执行操作#include "another.h",因为它是在 header.h 中开始的注释的一部分。

因此,不完整规则的规则避免了这些问题(这可能非常难以发现)。

If the file was empty anyway, this problem doesn't manifest: there's nothing like the #endif to be prepended to the next line in the including file....

于 2013-02-20T01:27:23.577 回答