45

このコードは Visual C++ 2013 では機能しますが、gcc/clang では機能しません。

#if 0
R"foo(
#else
int dostuff () { return 23; }
// )foo";
#endif
dostuff();

Visual C++ は最初に if 0 を削除します。Clang は最初に R の raw 文字列を展開します (dostuff を定義することはありません)。誰が正しいのか、その理由は?

4

2 に答える 2

38

[更新: 以下の Adrian McCarthy のコメントは、MSVC++ 2017 がこれを修正すると述べています]

GCC と clang は正しく、VC++ は間違っています。

2.2 翻訳のフェーズ [lex.phases]:

[...]

  1. ソース ファイルは、前処理トークン (2.5)と一連の空白文字 (コメントを含む)に分解されます。

  2. 前処理ディレクティブが実行され、[...]

2.5 トークンの前処理 [lex.pptoken]には、トークンの一覧が表示されますstring-literals

したがって、最初に文字列リテラルをトークン化し#elsedostuff関数定義を「消費」するために解析が必要です。

于 2015-06-23T08:12:29.053 に答える