使用 \ 扩展单行注释
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 中作为标准的一部分引入,尽管许多编译器已经支持它。
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本身就有规定
- 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
- 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
*/
除大型宏和字符串外,每次使用都会使代码更难阅读,甚至可能使代码变得相当混乱。所以一般除了提到的壁龛外,一般不用。
虽然 \
确实会在单行注释的末尾有效地转义换行符,将该行与下一行拼接(就像在任何其他行上所做的那样),但您可以声称这是标准中的错误。无论如何,情况非常混乱。您可能认为这两个事实都是真实的:
单行注释语法 //
将行的其余部分,直到下一个换行符,变成注释,不以任何方式解释,即被忽略。
在任何一行的末尾,\
字符消除换行符并将该行拼接到下一行。
但这两个规则基本上是冲突的;看起来它们不能同时为真。
事实上,根据定义,第二条规则 "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;\
我刚刚注意到我可以使用 \
将单行注释扩展到下一行,类似于在预处理器指令中这样做。
为什么没有人为这个语言功能发声? 书上也没看到。。 什么语言版本支持这个?
是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 中作为标准的一部分引入,尽管许多编译器已经支持它。
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本身就有规定
- 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
- 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
*/
除大型宏和字符串外,每次使用都会使代码更难阅读,甚至可能使代码变得相当混乱。所以一般除了提到的壁龛外,一般不用。
虽然 \
确实会在单行注释的末尾有效地转义换行符,将该行与下一行拼接(就像在任何其他行上所做的那样),但您可以声称这是标准中的错误。无论如何,情况非常混乱。您可能认为这两个事实都是真实的:
单行注释语法
//
将行的其余部分,直到下一个换行符,变成注释,不以任何方式解释,即被忽略。在任何一行的末尾,
\
字符消除换行符并将该行拼接到下一行。
但这两个规则基本上是冲突的;看起来它们不能同时为真。
事实上,根据定义,第二条规则 "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;\