源文件是否应该以新行结尾?反斜杠+换行符怎么样?

问题描述 投票:0回答:1

如果我们不以换行符结束源文件,而只是在 main() 之后使用

}
,则 clang 编译器(在严格模式下
-std=c17 -pedantic-errors
)臭名昭著的抱怨:

error: no newline at end of file [-Werror,-Wnewline-eof]

那么他们从哪里得到这个呢?它似乎取自 C17 5.1.1.2 翻译阶段,重点是我的:

紧跟换行符的反斜杠字符 (

\
) 的每个实例都是 删除,拼接物理源行以形成逻辑源行。仅最后一个反斜杠 任何物理源线都应有资格成为此类接头的一部分。 源文件是 非空应以换行符结尾,换行符前面不应紧接 发生任何此类拼接之前的反斜杠字符。

这首先描述了预处理器如何在存在

\
的情况下合并行。整个翻译阶段的目的似乎是专门描述行拼接,而不是一般的源文件。

最后一句似乎有些混乱。如果我以

\ (new line)
结束我的文件,那么现在 clang 突然让代码通过,直接违反了标准中上述引用的规范部分。然而,海湾合作委员会抱怨不符合规定:

错误:文件末尾的反斜杠换行符

当然,翻译阶段不是约束的一部分,因此编译器不会生成诊断。但为什么 clang 的行为却完全相反呢?

我检查了 C99 的基本原理,它说允许反斜杠 + 新行作为拼接行、字符串文字等的通用方式的意图是根据 C89 添加的,以实现最大的可移植性:“C89 委员会概括了这种机制,以允许任何令牌通过插入反斜杠/换行符序列来继续”。这就是为什么反斜杠+后面没有尾随标记的新行没有任何意义。

c clang language-lawyer c-preprocessor newline
1个回答
0
投票

主要问题是 C 文件是否应该以换行符结尾,如果是的话,C 标准中的哪里是这样规定的。翻译阶段部分是我能找到的唯一相关部分。

是的,这就是说源文件必须以(非转义)换行符结尾的部分。您对该要求的适用性表示怀疑,因为它与线路拼接规范捆绑在一起,但我不明白这有什么关系。 该规范要求在文件末尾有一个非转义换行符,结果是整个源文件(如果非空)必须具有一系列一个或多个换行符终止行的形式(在阶段结束时) 2,但这需要在第 2 阶段开始时进行相同的操作)。

如果规范只是想禁止源文件末尾的转义换行符,那么它会说“that”,并且相关语言会比它实际所说的更简单。 例如,这样的内容:“在进行此类行拼接之前,非空源文件不应以换行符结尾,紧接着反斜杠字符。” 我认为没有理由将源文件末尾对非转义换行符的要求解释为除了表面上所说的以外的任何含义。

额外的问题是为什么 clang 在以反斜杠 + 换行符结束源文件时看起来不符合标准

Clang 并没有不符合要求。 它接受不合格的源而不发出诊断,但只要不合格不涉及约束违规,合格的实现就允许这样做。 我倾向于猜测这个特定的遗漏与 Clang 作者的意图相反,因此它构成了程序缺陷,但你必须问他们。 可能通过提交错误报告。

无论如何,Clang的行为并不能被很好地定性为“落后”。 它确实诊断了一个“善意”的源代码一致性问题,但无法诊断另一个相关的问题。

© www.soinside.com 2019 - 2024. All rights reserved.