使用\来扩展单行注释

Ede*_*nia 8 c comments c-preprocessor

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

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

J..*_*..S 8

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

K&R书谈到了它

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

这发生在预处理阶段.

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

//This is \
still a single line comment
Run Code Online (Sandbox Code Playgroud)

与字符串的情况类似

char str[]="Hello \
world. This is \
a string";
Run Code Online (Sandbox Code Playgroud)

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

来自C99,

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

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

2.1.1.2翻译阶段

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

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


Ste*_*mit 6

虽然 a 确实\会有效地转义单行注释末尾的换行符,将该行与下一行拼接起来(就像在任何其他行上一样),但您可以声称这是标准中的一个错误。无论如何,情况非常令人困惑。您可能相信这两个事实都是正确的:

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

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

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

现在事实上,根据定义,第二条规则“获胜”,而第一条规则实际上必须说,除了检查最后一个字符是否是 a 之外,该行的其余部分不会以任何方式解释\,在这种情况下它保留其线路拼接的意思

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

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


chq*_*lie 5

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

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

// this is a single \
line comment
Run Code Online (Sandbox Code Playgroud)

请注意 stackoverflow 代码荧光笔是如何被这个技巧愚弄的,并且不会对注释行的末尾进行着色。

这个功能可以被进一步滥用,做出看起来很奇怪的评论:

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


/\
*\ This is a multi-line comment
*\
/
Run Code Online (Sandbox Code Playgroud)

任何令牌都可以通过这种方式破碎。检查这个极端情况:

\
r\
et\
urn\
 0x7\
ffff;\
Run Code Online (Sandbox Code Playgroud)

  • @KamiKaze:或者可以说*更糟糕*;-) (2认同)