gcc 4.7.1 が正しいです。規格によると、
c++11
2.2 翻訳の段階 [lex.phases]
1 - 変換の構文規則間の優先順位は、次のフェーズによって指定されます。[...]
3. ソース ファイルは、前処理トークン (2.5) と一連の空白文字 (コメントを含む) に分解されます。[...]
4. 前処理ディレクティブが実行され、マクロ呼び出しが展開されます。[...]
また、2.5 Preprocessing tokens [lex.pptoken] に従って、user-defined-string-literalは前処理トークンの生成です。
2.14.8 ユーザー定義リテラル [lex.ext]
ユーザー定義文字列リテラル:
文字列リテラル ud-suffix
ud-suffix :
識別子
したがって、 はすでにstring-literalとud-suffixで構成される単一のユーザー定義の文字列リテラル前処理トークンとして解析されているため、 のフェーズ 4 マクロ展開PRId64
は無関係です。"%"PRId64
"%"
PRId64
ああ、これは素晴らしいことです。誰もが変わらなければならない
printf("%"PRId64"\n", val);
に
printf("%" PRId64"\n", val); // note extra space
でも!gcc と clang は、ユーザー定義の文字列リテラルをサフィックスの先頭にアンダースコアを付けずに 2 つの別個のトークンとして扱うことに同意しました (整形式ではない基準に従って)。http://gcc.gnu.org/bugzilla/show_bug.cgi?id を参照してください。 =52538したがって、gcc の将来のバージョン (4.8 ブランチだと思います) では、既存のコードが再び機能するようになります。