次のコードは を出力するはずです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;
}
あなたは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 はこの種のトリッキーを検出し、警告を発しているようです (ちょうど set -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???/
^
関連資料:
このあごひげを生やしたスマイリーの表現は何ですか: "<:]{%>"?
そして、そこにある他のすべての同様の質問。??)
PS: スマイリーです。
??/
に置き換えられるTrigraph シーケンス\
です。
コンパイラにとっては\
、直後の行が現在の行の一部であることを意味します。この場合、現在の行はコメントです。効果的な結果は次のとおりです。
// Why won't this line work foo(x);
おそらく、あなたのコメントは、関数呼び出しを「削除」するトリグラフ (ツリーグラフではありません!) として解釈されます。
http://ideone.com/sU4YGcコメントで ??/ を削除するとうまくいきます。
// Why won't this line work?
foo(x);
C++ での Trigraph シーケンスの目的も参照してください。
// Why won't this line work???/
foo(x);
トライグラフ??/
が に変わる\
ので、コードは次のように変換されます。
// Why won't this line work?\
foo(x);
そして、文字列連結が機能します。
g++ でテストしたところ、trigraph はデフォルトでオフになっており (警告が生成されます)、6 が出力されます。 を使用してコンパイルするg++ t.cpp -trigraphs
と、5 が出力されます。
コンパイラはあなたの友達です。これ
// Why won't this line work???/
foo(x);
は複数行のコメントです。foo(x) は実行されません!
トリグラフ"??/" は、コメントへの改行を示す "\" に変換されます。