3

C ++ 11 2.5の場合トークンの前処理[lex.pptoken]:

条項16で説明されているように、変換フェーズ4の特定の状況では、空白(または空白がないこと)は、トークンの分離の前処理以上の役割を果たします。

これはどのような状況を指しているのですか?

4

2 に答える 2

8

フェーズ4では、空白が重要になる場合がいくつかあります。

  • 各前処理ディレクティブは、#「ソースファイルの最初の文字であるか、少なくとも1つの改行文字を含む空白の後に続く」トークンで始まります。各前処理ディレクティブは、改行文字で終了します。

  • 関数のようなマクロ定義では、パラメーターリストを開始する左括弧は、マクロに名前を付ける識別子の直後に続く必要があります。それらの間に空白があってはなりません。

    たとえば、ディレクティブ#define F()は何にも展開されない関数のようなマクロを#define F ()定義しますが、ディレクティブはに展開されるオブジェクトのようなマクロを定義します()

  • #空白は、マクロ置換中に演算子が評価される文字列化中に考慮されます。文字列化されるトークン間の空白のシーケンスは、結果の文字列リテラルで単一のスペースに折りたたまれます。

    たとえば、文字シーケンスf(x)はとして文字列化されますが、マクロ置換後のこれら2つの間に意味上の違いがない場合でも"f(x)"、文字シーケンスf ( x )はとして文字列化されます。"f ( x )"

エスケープされた改行文字はフェーズ2で削除され、各コメントはフェーズ3で単一のスペース文字に置き換えられることに注意してください。これらは両方ともフェーズ4の前に行われるため、フェーズ4ではエスケープされた改行は新しいものとしてカウントされません。 -行とコメントはスペース文字と区別できません。

于 2013-02-08T01:56:59.490 に答える
2

第16条は次のように述べています。

前処理中の特定の状況を除いて、すべての空白は同等です(たとえば、 cpp.stringizeの#文字列リテラル作成演算子を参照してください)。

#演算子[ccp.stringize]についてはこちらをご覧ください。関連情報は次のとおりです。

置換リストで、パラメーターの直前に #前処理トークンがある場合、両方が、対応する引数の前処理トークンシーケンスのスペルを含む単一の文字列リテラル前処理トークンに置き換えられます。引数の前処理トークンの間に空白が出現するたびに、文字列リテラルでは単一のスペース文字になります。最初の前処理トークンの前と、引数を構成する最後の前処理トークンの後の空白が削除されます。それ以外の場合、引数内の各前処理トークンの元のスペルは、文字列リテラルと文字リテラルのスペルを生成するための特別な処理を除いて、文字列リテラルに保持されます。\文字は、文字リテラルまたは文字列リテラル(区切り文字を含む)の各文字の"前に挿入されます。結果として生じる置換が有効な文字列リテラルでない場合、動作は未定義です。および演算子の評価の順序は指定されていません。\"###

于 2013-02-08T00:56:26.733 に答える