为什么&#34; foo \\ <newline> bar&#34;成为&#34; foo \ bar&#34;在&#34; gcc -E&#34;?之后

时间:2017-01-09 07:59:26

标签: c

参见以下示例:

$ cat foo.c
int main()
{
    char *p = "foo\\
bar";
    return 0;
}
$ gcc -E foo.c
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "foo.c"
int main()
{
    char *p = "foo\bar";

    return 0;
}
$

根据我的理解,第二个\被第一个\转义,因此第二个\不应与以下<NEWLINE>合并以形成续行。< / p>

2 个答案:

答案 0 :(得分:18)

规则在ISO / IEC 9899:2011§5.1.1.2翻译阶段中非常明确:

  
      
  1. 反斜杠字符(\)的每个实例后面紧跟一个换行符   删除字符,拼接物理源行以形成逻辑源行。   只有任何物理源代码行的最后反斜杠才有资格成为其中一部分   这种拼接。
  2.   

不会查询最终反斜杠之前的字符。阶段1将三字符转换为常规字符。这很重要,因为??/\的三字形。

答案 1 :(得分:16)

在尝试对输入进行标记化之前,预处理器会删除所有出现的反斜杠换行符;这没有逃避机制。它不仅限于字符串文字:

#inclu\
de <st\
dio.h>

int m\
ain(void) {
    /\
* yes, this is a comment */
    put\
s("Hello,\
 world!");
    return 0;
}

这是有效的代码。

使用\\获取单个\仅适用于字符串和字符文字,并且稍后会在处理中发生。