我有一个如下定义的数组:
extern const char config_reg[] = {
0x05, //comment
0x00, //comment
0x00, // \\ <-- double backslash
0x01, //comment
0x03
}
如您所见,注释中有一个双反斜杠(<-- double backslash
和前面的空格不会出现在实际的源文件中)。当我编译这段代码时(减去&#34;&lt; - 双反斜杠&#34;),就好像跟随行不存在 - 即相当于写作:
extern const char config_reg[] = {
0x05, //comment
0x00, //comment
0x00, //
0x03
}
这是C ++的行为吗?如果是这样,它的目的是什么?
我正在使用Parallax Propeller Simple IDE编译我的代码 - 所有帐户都不是一个特别好的编译器。编译器实现是否可能导致此行为?
答案 0 :(得分:2)
这是正确的,假设<-- double backslash
和前面的空格实际上不在代码中。
单个反斜杠也会产生相同的效果。
反斜杠 - 换行的换行符拼接分析之前发生了换行符,因此0x01
行与// \\
注释属于同一行,因此在评论分析完成时不会看到它
ISO / IEC 14882:2011(C ++ 11)标准说:
2.2翻译阶段[lex.phases]
¶1翻译语法规则的优先顺序由以下阶段指定: 11
物理源文件字符以实现定义的方式映射到基本源 字符集(如果需要,引入行尾指标的换行符)。这套物理 接受的源文件字符是实现定义的。 Trigraph序列(2.4)被替换 通过相应的单字符内部表示。任何源文件字符都不在基本字符中 源字符集(2.3)由指定该字符的通用字符名称替换。 (实现可以使用任何内部编码,只要是实际的扩展字符 在源文件中遇到,并且在源文件中表示的相同扩展字符为 通用字符名称(即使用
\uXXXX
表示法)的处理方式相同,除非此处 替换在原始字符串文字中还原。)删除后跟新行字符的反斜杠字符(
\
)的每个实例, 拼接物理源线以形成逻辑源线。任何物理上只有最后一个反斜杠 源线应有资格成为此类拼接的一部分。因此,如果是一个字符序列那么 匹配生成通用字符名称的语法,行为未定义。源文件 这不是空的,不会以换行符结尾,也不会以换行符结尾 在进行任何此类拼接之前,应立即使用反斜杠字符进行处理 好像在文件中附加了一个额外的换行符。- 醇>
源文件被分解为预处理令牌(2.5)和空白字符序列 (包括评论)。源文件不应以部分预处理标记或部分注释结束。 12 每个注释都被一个空格字符替换。保留换行符。是否 除了换行之外的每个非空白字符序列都保留或替换为1 空格字符未指定。将源文件的字符划分为预处理标记的过程 是依赖于上下文的。 [示例:查看
<
预处理指令中#include
的处理。 - 结束示例]11)实现必须表现得就像这些单独的阶段一样,尽管在实践中不同的阶段可能会被折叠 在一起。
12)部分预处理令牌将来自以多字符令牌的第一部分结尾的源文件 需要一个终止字符序列,例如缺少结束
"
或>
的标题名称。部分评论 将来自以未公开的/*
评论结尾的源文件。
答案 1 :(得分:1)
是的,翻译的第二阶段涉及&#34;拼接物理源线以形成逻辑源线&#34 ;;如果一行以反斜杠结尾,则以下行被视为该行的延续。这是标准行为。在第三阶段删除评论之前发生,因此评论中出现反斜杠这一事实并没有改变任何内容。
在C中经常使用行拼接来将宏分割为多行,因为预处理程序指令会扩展到行的末尾。它在C ++中非常罕见,它在宏上的依赖性远远低于C。
我认为C中的最初目的是解决现在一些古老系统中存在的线路长度限制。
答案 2 :(得分:1)
一行末尾的\
会转义换行符。
因此,在您的示例中,它会将注释扩展到下一行。该片段的作者可能使用\\
代替\
用于审美目的。但它并不仅仅适用于评论。例如,这是允许的(但是多余的):
int a; \
int b;
某些编译器允许\
和换行符之间的空格,但可能会发出警告。