以下代码应输出6
,但输出5
。我无法弄清楚为什么。发生了什么事?
#include <iostream>
template <typename T>
void foo(T& y)
{
y++;
}
int main()
{
int x = 5;
// Why won't this line work???/
foo(x);
std::cout << x;
}
答案 0 :(得分:21)
你正在使用trigraphs的好技巧。
// Why won't this line work???/
| |
\ /
|
~trigraph~
??/
三元组又转换为\
,它基本上将当前行与下一行连接起来,因此您的代码或多或少会像这样:
// Why won't this line work? foo(x);
确实是一个很好的技巧。
引用C ++ 11标准:
§2.2.2:
反斜杠字符(\)的每个实例后面紧跟着一个 删除新行字符,拼接物理源行以形成 逻辑源代码行。 ...
第2.4.1节:
Table 1 - Trigraph sequences
...
==========================
| Trigraph | Replacement |
==========================
| ... |
==========================
| ??/ | \ |
==========================
幸运的是,GCC seems to detect this kind of trickery发出了警告(仅设置了-Wall
):
main.cpp:13:32: warning: trigraph ??/ converted to \ [-Wtrigraphs]
// Why won't this line work???/
^
main.cpp:13:4: warning: multi-line comment [-Wcomment]
// Why won't this line work???/
^
<子> 相关参考文献:
What is this smiley-with-beard expression: "<:]{%>"?
What does the C ??!??! operator do?
还有其他类似的问题。 ??)
PS:那是个笑脸。
答案 1 :(得分:8)
??/
是一个 Trigraph序列,被替换为\
。
对于编译器\
意味着后面的立即行是当前行的一部分。在这种情况下,当前行是注释。有效的结果是:
// Why won't this line work foo(x);
答案 2 :(得分:4)
Trigraphs 。在c ++ 11规范中
2.4 Trigraph sequence [lex.trigraph]
1 在进行任何其他处理之前,每次出现以下三个字符序列之一 (“trigraph sequences”)被表1中所示的单个字符替换。
Table 1 — Trigraph sequences Trigraph Replacement │ Trigraph Replacement │ Trigraph Replacement ─────────────────────┼──────────────────────┼───────────────────── ??= # │ ??( [ │ ??< { ??/ \ │ ??) ] │ ??> } ??’ ˆ │ ??! | │ ??- ~
现在将??/
替换为\
,您就会发现。
答案 3 :(得分:2)
// Why won't this line work???/
foo(x);
三字母??/
变为\
,因此代码将转换为:
// Why won't this line work?\
foo(x);
字符串连接有效。
当我用g ++测试它时,默认情况下关闭trigraph(生成警告),它将输出6.如果使用g++ t.cpp -trigraphs
编译,将输出5.
答案 4 :(得分:2)
可能你的评论被解释为“删除”函数调用的三字符(而不是treegraph!)。
http://ideone.com/sU4YGc适用于我在评论中删除?? /。
// Why won't this line work?
foo(x);
答案 5 :(得分:1)