13

一部のコードをGCC4.7(4.6から)に移行し、いくつかのコンパイラエラーが発生し、GCC4.7移植ガイドに記載されている問題を見つけました。

ユーザー定義のリテラルと空白

ISOC11モードのC++コンパイラはstd={c++11,c++0x,gnu++11,gnu++0x} 、一部の有効なISO C++03コードと互換性のないユーザー定義リテラルをサポートしています。

特に、文字列リテラルの後、有効なユーザー定義リテラルになる可能性のあるものの前に空白が必要になりました。有効なISOC++03コードを取得します

const char *p = "foobar"__TIME__;

C ++ 03では、TIMEマクロはある文字列リテラルに展開され、他の文字列と連結されます。C ++ 11__TIME__では拡張されておらず、代わりoperator "" __TIME__に検索されているため、次の診断が行われます。

error: unable to find string literal operator  ‘operator"" __TIME__’

これは、空白なしでマクロが続くすべての文字列リテラルに適用されます。修正するには、文字列リテラルとマクロ名の間に空白を追加するだけです。

エラーを修正することはできますが、なぜこれを実行する必要があるのか​​を知りたいのです。__TIME__はマクロであるため、前処理段階で(または同様の)に"something"__TIME__変更される"something""15:52:03"ため、コンパイラはそれをとして見る機会がありませんoperator ""

この動作は標準で承認されていますか、それともバグですか?

4

1 に答える 1

16

問題は、が続く"foobar"__TIME__プリプロセッサ トークンにトークン化されなくなったことです。"foobar"__TIME__

プリプロセッサ トークンには、「キーワード、識別子、リテラル、演算子、または句読点の字句形式があります」。ユーザー定義のリテラルを追加すると、プリプロセッサ トークンとしてレクシングされるものが変わります。現在"foobar"__TIME__は単一のユーザー定義文字リテラルプリプロセッサ トークンであるため、変換のフェーズ 4 が発生すると、__TIME__に置き換えられますが、この方法で置き換えられるトークン"15:52:03"はありません。__TIME__

はい、この動作は標準で指定されています。

cinttypes マクロが原因で、委員会が認識したよりも多くのコードが影響を受けているようで、委員会はそれに対処することを検討しています。一部のコンパイラはすでに cinttypes の問題を処理するように移行していますが、この使用法を修正する方法ではあり__TIME__ません。あなたの最善の策は、コードを変更することだと思います。

于 2012-08-10T22:09:03.450 に答える