问题描述
有效代码:
#define M xxx\
yyy
无效的代码:
#define M xxx\/*comment*/
yyy
#define M xxx\//comment
yyy
问题:
- 为什么反斜杠字符(
\
)后面不允许注释? - 标准怎么说?
UPD。 额外的问题:
- (为了实现物理源代码行的拼接)反斜杠字符(
\
)必须紧跟换行符的要求背后的动机/原因/论据是什么?在反斜杠字符(\
)后允许注释(或空格)的障碍是什么?
解决方法
仅当反斜杠字符是行中的最后一个字符时,才将行拼接在一起。 C 2018 5.1.1.2指定翻译C程序的阶段。在阶段2:
每个反斜杠字符()紧跟换行符的实例都将被删除,将物理源代码行拼接以形成逻辑源代码行……
如果注释在反斜杠字符之后,则反斜杠字符后不跟换行符,因此不会执行拼接。注释在阶段3中处理:
源文件被分解为预处理令牌7)和一系列空格字符(包括注释)……每个注释都替换为一个空格字符……
关于添加的问题:
(为了实现物理源代码行的拼接)反斜杠字符(
\
)必须紧跟换行符的要求背后的动机/原因/论据是什么?在反斜杠字符(\
)后允许注释(或空格)的障碍是什么?
最早的编译C程序的过程是最简单的。早期的C编译器可能已实现为简单的过滤器层:首先将本地环境字符或文件存储方法转换为简单的字符流,然后将行拼接在一起(也许处理需要较长源代码的问题行,同时必须在80列打孔卡上键入源代码),然后注释将被删除,依此类推。
在行尾将反斜杠标记的行拼接在一起很容易;它只需要查看两个字符。相反,如果我们允许注释在标记为剪接的反斜杠之后,则会变得很复杂:
- 将拼接反斜杠,后跟注释,然后换行,但是不会反斜杠,后跟注释,再加上其他源代码。这就需要在前面查找很多字符并解析注释定界符,可能需要多个注释。
- 拼接线的目的之一是允许多行连续的长字符串。 (这是在相邻字符串之间用C连接之前。)因此,一行上的
"abc\
和另一行上的def"
将被拼接在一起,形成"abcdef"
。虽然我们可能允许在反斜杠后加入行的注释,但我们不想在包含"abc\ /*" /*comment*/
的行之后进行拼接。这意味着进行拼接的代码必须对上下文敏感。如果反斜杠出现在带引号的字符串中,则必须将其区别对待。
实际上是在删除注释之前处理反斜杠换行符的原因。这就是为什么完全删除反斜杠换行符,而不是像注释一样用(虚拟)水平空格代替的原因。这是荒谬的原因,但这是官方原因。这样一来,无论发生什么除法,您都可以通过在第79列插入反斜杠换行符,将长行的C代码机械地强制拟合到打孔卡上。
static int cp_old_stat(struct kstat *stat,struct __old_kernel_stat __user * st\
atbuf)
{
static int warncount = 5;
struct __old_kernel_stat tmp;
if (warncount > 0) {
warncount--;
printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Re\
compile your binary.\n",
(这是我在硬盘驱动器上发现的第一个C块,实际上它的行不适合打孔卡)
要使此功能按预期工作,反斜杠换行符必须能够拆分/*
或*/
,例如
/* this comment just so happens to be exactly 80 characters wide at the close *\
/
您不能同时使用这两种方法:如果要在处理反斜杠换行符之前删除注释,则反斜杠换行符不会影响注释边界。相反,如果要先处理反斜杠换行符,则注释不能出现在反斜杠和换行符之间。
(我不是在做这个™:C99 Rationale第5.1.1.2节第30段显示为
换行符之前的反斜杠早已用于继续字符串文字以及预处理命令行。为了简化C的机器生成,以及将代码传输到物理行长受限制的机器,C89委员会对此机制进行了概括,以允许通过插入反斜杠/换行符序列来继续 any 令牌。
强调原始内容。抱歉,我不知道该文档的任何非PDF版本。)
,每5.1.1.2 Translation phases of the C11 standard(注意添加的粗体文本)
5.1.1.2翻译阶段
1翻译的语法规则中的优先级由以下阶段指定。6)
1必要时,将物理源文件多字节字符以实现定义的方式映射到源字符集(为行尾指示符引入换行符)。 Trigraph序列被相应的单字符内部表示代替。
2 每个反斜杠字符(\)紧跟换行符的实例都将被删除,从而将物理源代码行拼接成逻辑源代码行。只有任何物理源行上的最后一个反斜杠才有资格成为此类拼接的一部分。非空的源文件应以换行符结尾,并且不得紧接在反斜杠字符之后在进行任何此类拼接之前。
...
仅反斜杠字符后紧跟换行符将导致对行进行拼接。评论不是换行符。