使用\来扩展单行注释

时间:2018-06-14 13:07:47

标签: c comments c-preprocessor

我刚注意到我可以使用\将单行注释扩展到下一行,类似于在预处理器指令中这样做。

为什么没有人说这种语言功能? 我甚至没有在书中看到它.. 什么语言版本支持这个?

4 个答案:

答案 0 :(得分:8)

它是C.被称为线拼接的一部分。

K& R书谈到它

  

以反斜杠字符\结尾的行通过删除反斜杠和折叠来折叠   跟随换行符。这在分成令牌之前发生。

这发生在预处理阶段。

因此,可以使单行注释看起来像多行,如

//This is \
still a single line comment

与字符串的情况相同

char str[]="Hello \
world. This is \
a string";

编辑:正如评论中所指出的那样,单行注释在ANSI C中不存在,但作为C99标准的一部分引入,尽管许多编译器已经支持它。

From C99

  

除了字符常量,字符串文字或注释之外,字符//引入的注释包括所有多字节字符,但不包括下一个换行符。检查此类注释的内容仅用于标识多字节字符并查找终止的换行符。

就线拼接而言,它在C89本身中指定

2.1.1.2 Translation phases

  
      
  1. 删除新行字符和紧接在前的反斜杠字符的每个实例,拼接物理源行以形成逻辑源行。非空的源文件应以换行符结尾,换行符前面不应有反斜杠字符。
  2.   

看看KamiKaze的答案,看看C99的相关部分。

答案 1 :(得分:4)

这不是评论的功能,而是该语言的一般功能,因为它适用于所有换行符。

以下内容可在C99 standard中找到:

  

5.1.1.2翻译阶段

     
      
  1. 删除紧跟着换行字符的每个反斜杠字符()实例,拼接物理源代码行以形成逻辑源代码行。只有任何物理源线上的最后反斜杠才有资格成为此类拼接的一部分。非空的源文件应以换行符结尾,在进行任何此类拼接之前,该换行符不应立即以反斜杠字符开头。
  2.   

因此它至少符合C99标准。 它没有太多讨论,因为相关的用例(大型宏和字符串除外)是非常罕见的。如果您需要多行注释(C中的标准注释,//稍后从C ++添加),您可以使用

/* multi
   line
   comment
*/

除了大型宏和字符串之外的每次使用都会使代码更难以阅读,甚至可能使它变得非常混乱。因此,除了上面提到的利基之外,通常不会使用它。

答案 2 :(得分:3)

在解析的第一阶段,在标记化和注释处理之前,每个\后跟换行符的实例都会从源中删除。

因此,通过使用\(或??/三字符序列转义此换行符,可以将单行注释扩展到下一行源代码:

// this is a single \
line comment

注意stackoverflow代码突出显示器是如何被这个技巧所欺骗的,并且没有为注释行的末尾着色。

此功能可以进一步滥用,以制作看起来很奇怪的评论:

/\
/\  This is a single line comment /\
\/                                \/


/\
*\ This is a multi-line comment
*\
/

任何令牌都可以这样破碎。检查此角落案例:

\
r\
et\
urn\
 0x7\
ffff;\

答案 3 :(得分:2)

虽然\在单行评论结束时会有效地逃脱换行,但是拼接该行与下一行(就像在任何其他行上一样),这是正确的,你可以声称这是标准中的一个错误。无论如何,这种情况非常令人困惑。您可能认为这两个事实都是正确的:

  1. 单行注释语法//将该行的其余部分(直到下一个换行符)转换为注释,该注释不会以任何方式解释,即被忽略。

  2. 在任何行的末尾,\字符会删除换行符并将该行拼接到以下行。

  3. 但这两条规则基本上是冲突的;看起来他们两个都不能同时成真。

    现在事实上,根据定义,第二条规则"胜出#34;并且第一条规则确实必须说该线的其余部分不以任何方式解释,除了检查是否最后一个字符是\,在这种情况下,它保留了其行拼接含义

    (现在,如果你是一名编译作家或语言律师,当然,你不会那么想。如果你是编译作家或语言律师,你知道吗? \在编译的早期阶段处理,在解析注释之前处理,这意味着第一条规则完全正确,如上所述。但大多数人并不像编译器编写者和语言律师那样思考。)< / p>

    我的观点是,这种情况基本上充满了危险。我敢打赌,那里有编译器或其他语言处理器可以解决这个问题。我会敦促任何理智的程序员依赖于此,而不是将\放在包含单行注释的任何行的末尾。 (如果我正在编写编译器或其他语言处理器,我会尝试警告这一点。)