数组内注释中的双反斜杠

Double backslash in comment inside array

本文关键字:注释 数组      更新时间:2023-10-16

我有一个定义如下的数组:

extern const char config_reg[] = {  
  0x05, //comment
  0x00, //comment
  0x00, //  \    <-- double backslash
  0x01, //comment
  0x03
}

正如您所看到的,注释中有一个双反斜杠(<-- double backslash和前面的空格不会出现在实际的源文件中)。当我编译此代码(减去"<--双反斜杠")时,它的作用就好像下面的行不存在一样,即相当于写入:

extern const char config_reg[] = {  
  0x05, //comment
  0x00, //comment
  0x00, //  
  0x03
}

这是预期的C++行为吗?如果是,其预期目的是什么?

我正在使用Parallax Propeller Simple IDE编译我的代码——所有人都认为这不是一个特别好的编译器。是否可能是编译器实现导致了这种行为?

这是正确的,假设<-- double backslash和前面的空格实际上不在代码中。

一个反斜杠也会产生同样的效果。

反斜杠换行符的换行符拼接发生在注释分析之前,因此0x01行与// \注释是同一行的一部分,因此在注释分析完成时看不到它。

ISO/IEC 14882:2011(C++11)标准规定:

2.2翻译阶段[法律阶段]

¶1翻译的语法规则之间的优先顺序由以下阶段规定11

  1. 物理源文件字符以实现定义的方式映射到基本源字符集(为行尾指示符引入换行符)(如有必要)。物理接受的源文件字符是由实现定义的。替换了三角图序列(2.4)通过相应的单字符内部表示。任何不在基本中的源文件字符源字符集(2.3)被指定该字符的通用字符名所代替。(一个实现可以使用任何内部编码,只要实际的扩展字符在源文件中遇到,并且源文件中表示的扩展字符与通用字符名(即使用uXXXX表示法)的处理是等效的,除非替换被还原为原始字符串文字。)

  2. 紧接着一个新行字符的反斜杠字符()的每个实例被删除,拼接物理源线以形成逻辑源线。只有任何物理上的最后一个反斜杠源线应有资格成为此类拼接的一部分。因此,如果一个字符序列如果生成了语法匹配的通用字符名,则行为未定义。源文件不为空且不以换行符结尾的,或以换行符结束的在进行任何此类拼接之前,应立即处理前面有反斜杠字符的就好像一个额外的换行符被附加到文件中一样。

  3. 源文件被分解为预处理令牌(2.5)和空白字符序列(包括评论)。源文件不应以部分预处理标记或部分注释结尾12每个注释由一个空格字符代替。保留新行字符。是否除了新行之外,每个空白字符的非空序列都被保留或替换为一个空格字符未指定。将源文件的字符划分为预处理标记的过程取决于上下文。[示例:请参阅#include预处理指令中对<的处理。--结束示例]

11)实现必须表现为这些单独的阶段发生,尽管在实践中可能会折叠不同的阶段在一起

12)部分预处理令牌将由以多字符令牌的第一部分结尾的源文件产生需要终止字符序列,例如缺少结束">的标头名称。部分评论源文件以未关闭的CCD_ 11注释结尾。

是的,翻译的第二阶段涉及"拼接物理源行以形成逻辑源行";如果一行以反斜杠结尾,则下一行被视为该行的延续。这是标准行为。这发生在第三阶段删除注释之前,因此注释中出现的反斜杠不会改变任何内容。

行拼接在C中非常频繁地用于将宏拆分为多行,因为预处理器指令会延伸到行的末尾。它在C++中要少得多,因为它比C.更不依赖宏

我相信C的最初目的是绕过一些现在已经过时的系统中存在的线路长度限制。

行尾的转义换行符。

因此,在您的示例中,它将把注释扩展到下一行。出于美观的目的,这个片段的作者可能使用了\而不仅仅是。但它不仅仅适用于评论。例如,这是允许的(但冗余):

int a; 
int b;

某些编译器允许和换行符之间存在空白,但可能会发出警告。