FAQ

QA・C/QA・C++

QA・C++ 特有のFAQ

ID.

Q. 置換文字列内で##を使用しているマクロから同様のマクロを呼び出すと解析できないのでしょうか? QA・C++ の全バージョン

A.


マクロの記述内容によっては、ISO C++違反の構文になるため解析することができません。

ISO C++言語規格書の16.3.4には次の規則が記されています。

オブジェクト形式マクロ 及び 関数形式マクロのいずれの呼出しにおいても, その置換内容列を再検査して, 更に置き換えるべきマクロ名があるかどうか を調べる前に, 置換内容列中の各前処理字句## (実引数からもたらされた 前処理字句 ## は除く。) の出現を削除し, その直後にある前処理字句と その直後の前処理字句とを連結する。例えば、次のようなコードを記述した場合、 #define MACRO1(x) func(data_ ## x) #define MACRO2(y) MACRO1(## y ##) #define ONE 1 void func(int x) {} int main(void) { int data_1 = 1; MACRO2(ONE); return 0; }MACRO2の展開結果は、data_1 にはなりません。MACRO2の展開結果は、data_ONE になります。これは、MACRO1とMACRO2の両方のマクロが、置換文字列内で##を使用し、 MACRO2がMACRO1を呼び出しているので、ISO C++に従った場合、 ONEが独立したマクロとして認識されるよりも前に、 data_ONEという文字列が生成されるからです。
QA C++はISO C++に従って解析し、MACRO2(ONE) を data_ONE に展開するので、 上記のコードをエラーとして扱います (該当箇所には400番の警告が出力されます)。
本問題に遭遇した場合は、恐れ入りますが、適宜回避策があるかどうかを ご相談ください。
なお、上記のコードの場合は、 「MACRO1(## y ##) → MACRO1(y)」に記述し直すことができれば、 ISO C++に従った構文になるので、QA C++が正しく解析できるようになります。

<< QA・C++ 特有のFAQに関するFAQ一覧へ戻る