そんなこと知ってる:
_#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"
_。
どうして?プロセスに含まれるステップは何ですか?
マクロ展開の関連する手順は次のとおりです(C 2011 [n1570] 6.10.3.1およびC++ 1998 16.3.1による):
#
_または_##
_で始まるトークンを処理します。したがって、xstr(foo)
を使用すると、次のようになります。
str(s)
には_#
_または_##
_が含まれていないため、何も起こりません。foo
は_4
_に置き換えられているため、xstr(4)
が使用されたかのようになります。str(s)
では、パラメーターs
が_4
_に置換され、str(4)
が生成されます。str(4)
が再スキャンされます。 (結果のステップは_”4”
_を生成します。)str(foo)
の問題は、ステップ2がfoo
を_4
_に置き換えるステップ2であることに注意してください。ステップ1は引数を文字列に変更します。ステップ1では、foo
はfoo
のままです。 _4
_に置き換えられていないため、結果は_”foo”
_になります。
これが、ヘルパーマクロが使用される理由です。ステップ2を実行してから、別のマクロを使用してステップ1を実行できます。
str(foo)
の評価:str(foo)
を_#foo
_に置き換えます。つまり、_"foo"
_xstr(foo)
の評価:xstr(foo)
をstr(<foo-value>)
に置き換えます。つまり、str(4)
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' ;
}
_
のように評価します
str(foo)
を_<foo-value> + 1
_に置き換える、つまり_4 + 1
_結果は4 + 1
xstr(foo)
をstr(<foo-value>) + 1
に置き換える、つまりstr(4) + 1
str(4)
を_<4-value> + 1
_に置き換える、つまり_4 + 1
_結果は4 + 1 + 1です