【发布时间】:2017-10-16 21:21:28
【问题描述】:
是否有广泛使用的 pre-ANSI C 编译器†要求# 位于第一列?
† 我会接受this list 上的任何编译器。如果我能在 comp.lang.c Usenet 新闻组中 1995 年之前的帖子中找到提及它,我会接受它。
K&R C 没有指定# 之前是否允许空格。来自原始The C Programming Language,附录 A 中“C 参考手册”的§12¶1:
C 编译器包含一个能够进行宏替换、条件编译和包含命名文件的预处理器。以
#开头的行与此预处理器进行通信。
因此,未指定是否允许在 # 之前使用空格。这意味着如果指令不是从第一列开始,则 pre-ANSI 编译器可能无法编译程序。
在 ISO C(以及之前的 ANSI C)中,明确允许 C 预处理指令以空格作为前缀。在 ANSI C (C-89) 中:
预处理指令由一系列预处理组成 以
#预处理令牌开头的令牌,即 源文件中的第一个字符(可选在空格之后 不包含换行符)或后面的空格 至少包含一个换行符,并由下一个结束 换行符。
ISO C.2011 有类似的语言,但进一步澄清:
预处理指令由一系列满足 以下约束:序列中的第一个标记是
#预处理标记(在 翻译阶段 4 的开始)是源文件中的第一个字符(可选 在不包含换行符的空格之后)或在空格之后 至少包含一个换行符。序列中的最后一个标记是第一个换行符 序列中第一个标记之后的字符。165) 换行符结束 预处理指令,即使它出现在函数类宏的调用中。
165) 因此,预处理指令通常称为“行”。这些“行”没有其他句法 意义,因为除了在预处理期间的某些情况下,所有空白都是等价的(请参阅 以#6.10.3.2 中的字符串字面量创建运算符为例)。
【问题讨论】:
-
有人在对最近一个问题的评论中确实提到了这一点,但 MSVC 不要求
#include的#位于第一列。 -
@WeatherVane:是的,这是一个关于旧 C 编译器的问题,在 ANSI 要求预处理器允许空白位于
#之前。 -
在 pre-ansi C 的上下文中“广泛使用”是什么意思?
-
@rici:在问题中澄清了这一点。
-
@rici:据我回忆,在 ANSI 之前有一些非常流行的 C 编译器。当然还有最初的 Ken Thompson 的 C 编译器。 Stephen Johnson 有最初的可移植 C 编译器 (pcc)。我有一个支持 C 语言的旧 SuperPET,但我不确定它的起源。大多数 90 年代早期供应商推出的 C 编译器仍然支持 pre-ANSI C,因为大多数 C 软件源代码都是以这种风格编写的。
标签: c c-preprocessor kernighan-and-ritchie