1. ホーム
  2. c

[解決済み] ダブルストリングスのトリックは、具体的にどのように機能するのですか?

2023-04-27 07:41:05

質問

少なくともいくつかの C プリプロセッサでは、マクロを文字列化する別の関数にマクロを渡すことで、マクロの名前ではなく、値を文字列化することができます。

#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */

使用例 ここで .

これは、少なくともGCCとClangでは動作します(両方とも -std=c99 で)、しかし、私は はどのように が C 標準の用語でどのように機能するかはわかりません。

この動作はC99で保証されているのでしょうか?

もしそうなら、C99はどのようにそれを保証するのでしょうか?

そうでない場合、どの時点で動作がC-definedからGCC-definedになるのでしょうか?

どのように解決するのですか?

はい、保証します。

マクロへの引数はそれ自体がマクロ展開されるため、動作します。 を除いて で、マクロ引数名がマクロ本体で文字列子 # またはトークンパスタ ## と共に表示される場合に機能します。

6.10.3.1/1:

... の引数の後に 関数型マクロの呼び出しの が識別された後、引数の置換が行われます。 の置換が行われます。引数 は、置換リスト中の の前に#または##前処理トークンがあるか トークンが先行するか、##前処理トークンが後続する場合を除き、置換リスト内のパラメータは 前処理トークン(下記参照)がない限り,置換リスト中のパラメータは 対応する引数で置き換えられます。 に置き換えられる。 が展開された後、対応する引数に置き換えられます。

ということは、もしあなたが STR1(THE_ANSWER) とすると、STR1の引数はマクロ展開されていないので、"THE_ANSWER"が得られます。しかし、STR2 の引数は の引数はマクロ展開され、STR2 の定義に代入されるため、STR1 の引数は 42 となり、結果は "42"となります。