web-dev-qa-db-ja.com

文字列化-どのように機能しますか?

そんなこと知ってる:

_#define foo 4  
#define str(s) #s
_

with str(foo)は次を書き出します:_"foo"_、stringifyはテキスト展開の最初に実行されるため、これは:

_ #define xstr(s) str(s)
 #define str(s) #s
 #define foo 4
_

with xstr(foo)は次を書き出します:_"4"_。

どうして?プロセスに含まれるステップは何ですか?

49
Marco A.

マクロ展開の関連する手順は次のとおりです(C 2011 [n1570] 6.10.3.1およびC++ 1998 16.3.1による):

  1. _#_または_##_で始まるトークンを処理します。
  2. 各引数にマクロ置換を適用します。
  3. 各パラメーターを、上記のマクロ置換の対応する結果に置き換えます。
  4. 他のマクロを再スキャンします。

したがって、xstr(foo)を使用すると、次のようになります。

  1. 置換テキストstr(s)には_#_または_##_が含まれていないため、何も起こりません。
  2. 引数fooは_4_に置き換えられているため、xstr(4)が使用されたかのようになります。
  3. 置換テキストstr(s)では、パラメーターsが_4_に置換され、str(4)が生成されます。
  4. str(4)が再スキャンされます。 (結果のステップは_”4”_を生成します。)

str(foo)の問題は、ステップ2がfooを_4_に置き換えるステップ2であることに注意してください。ステップ1は引数を文字列に変更します。ステップ1では、foofooのままです。 _4_に置き換えられていないため、結果は_”foo”_になります。

これが、ヘルパーマクロが使用される理由です。ステップ2を実行してから、別のマクロを使用してステップ1を実行できます。

55

最初のケース

  1. str(foo)の評価:str(foo)を_#foo_に置き換えます。つまり、_"foo"_

2番目のケース

  1. xstr(foo)の評価:xstr(foo)str(<foo-value>)に置き換えます。つまり、str(4)
  2. str(4)の評価:str(4)を_#4_に置き換えます。つまり、_"4"_

一般的に、

プリプロセッサは、マクロ変数を展開するマクロ関数を評価します評価するものがなくなるまで

定義する場合

_#define xstr(s) str(s) + 1
#define str(s) s + 1
_

次のコードで

_#define foo 4

int main()
{
    std::cout << str(foo) << '\n' 
              << xstr(foo) << '\n' ;

} 
_

のように評価します

最初の文字列

  1. str(foo)を_<foo-value> + 1_に置き換える、つまり_4 + 1_
  2. これ以上代用するものはありません。仕上げ。

結果は4 + 1

2番目の文字列

  1. xstr(foo)str(<foo-value>) + 1に置き換える、つまりstr(4) + 1
  2. str(4)を_<4-value> + 1_に置き換える、つまり_4 + 1_
  3. これ以上代用するものはありません。

結果は4 + 1 + 1です

13
Lol4t0