使用 \ 扩展单行注释

Using \ to extend single-line comments

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

为什么没有人为这个语言功能发声? 书上也没看到。。 什么语言版本支持这个?

是C的一部分,叫做行拼接

K&R 书中有讲到

Lines that end with the backslash character \ are folded by deleting the backslash and the following newline character. This occurs before division into tokens.

这发生在预处理阶段。

所以单行注释可以变成多行注释

//This is \
still a single line comment

字符串的情况也是如此

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

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

From C99,

Except within a character constant, a string literal, or a comment, the characters // introduce a comment that includes all multibyte characters up to, but not including, the next new-line character. The contents of such a comment are examined only to identify multibyte characters and to find the terminating new-line character.

关于行拼接,C89本身就有规定

2.1.1.2 Translation phases

  1. Each instance of a new-line character and an immediately preceding backslash character is deleted, splicing physical source lines to form logical source lines. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character.

看神风的回答可以看到C99的相关部分。

这不是注释的特性,而是语言的一般特性,因为它适用于所有换行符。

C99 standard 中找到以下内容:

5.1.1.2 Translation phases

  1. Each instance of a backslash character () immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.

所以它至少符合 C99 标准。 不多谈,因为相关用例(大型宏和字符串除外)很少见。如果您需要多行注释(C 中的标准注释,// 是后来从 C++ 中添加的),您可以只使用

/* multi
   line
   comment
*/

除大型宏和字符串外,每次使用都会使代码更难阅读,甚至可能使代码变得相当混乱。所以一般除了提到的壁龛外,一般不用。

虽然 \ 确实会在单行注释的末尾有效地转义换行符,将该行与下一行拼接(就像在任何其他行上所做的那样),但您可以声称这是标准中的错误。无论如何,情况非常混乱。您可能认为这两个事实都是真实的:

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

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

但这两个规则基本上是冲突的;看起来它们不能同时为真。

事实上,根据定义,第二条规则 "wins" 和第一条规则确实必须说明该行的其余部分不会以任何方式解释 除了检查是否最后一个字符是 \,在这种情况下它保留其行拼接意义

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

我的观点是,这种情况基本上充满了危险。我敢打赌,有些编译器或其他语言处理器会出错。我会敦促任何理智的程序员 而不是 依赖于此,不要在包含单行注释的任何行的末尾放置 \ 。 (如果我正在编写编译器或其他语言处理器,我会尝试对此发出警告。)

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

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

// this is a single \
line comment

请注意 Whosebug 代码高亮器是如何被这个技巧愚弄的,并且不会为注释行的末尾着色。

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

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


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

任何令牌都可以用这种方式分解成碎片。检查这个角落案例:

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