2012-03-01 9 views
2

マクロの展開を追跡したい - マクロが展開された回数と展開が行われたときのargは何か?例えばマクロの展開を追跡する

私はマクロは次のようになりますしている:プリプロセッサの終わりに

mymacro(a); 
mymacro(b); 

#define mymacro(x) int x 

と私のコードでは、私はこのような何かを持っています拡張(ああ、特定のマクロを最後に展開する方法はありますか?)、mymacroが何回使用されたのか、また渡されたargsについて知りたいと思います。この場合、2回、argsはaとbになります。

私はブーストプリプロセッサlibを調べていました。彼らはBOOST_PP_ARRAYを持っていますが、私はそれを "静的"にする方法を知らないので、後でそれを使うことができます。

BOOST_PP_COUNTERに何かが見つかりました。 BOOST_PP_COUNTERはプリプロセッサ・フレーズで状態を維持できるものです。しかし、私は、私が望んでいたことをどうやってやるか、まだ不明です。

+0

これは、コンパイラがサポートしている場合は、コンパイラメッセージを出力するマクロに行を追加することで可能です。 –

+0

あなたはもっと具体的になることができますか?私はClangを使用しています –

+0

すぐにはわかりませんが、何が起きているのかについて過去の検査をしていて、何かをすることができるように前処理時に利用できるようにしたいそれで、そう? –

答えて

0

どうやってこのようにしますか?

#include <iostream> 

int m_counter = 0; 
const char *m_arguments[32] = { 0 }; 

#define COUNT_M(a) m_arguments[m_counter++] = #a; 
#define M(a) COUNT_M(a) int a 

int main() 
{ 
    M(x); 
    M(y); 

    for (int i = 0; i < m_counter; i++) 
    { 
     std::cout << "m_arguments[" << i << "] = \"" << m_arguments[i] << "\"\n"; 
    } 
} 
+0

hmm ...この場合、M(x)とM(y)は実行時に、動作するようにします。私のマルコスはコールバックなので、呼び出されるのは簡単ではありません。とにかくこれをコンパイル時に行うには? –

0

私はあなたの究極の目標が何であるかはかなりわからないんだけど、あなたはアクティブな引数を使用してスキャン数(拡張のない数)を追跡することができます。アクティブな引数は、プリプロセッサによってスキャンされるたびに展開されます。例えば、Aの

#define EMPTY() 

#define A(n) \ 
    A_INDIRECT EMPTY()()(BOOST_PP_INC(n)) 

#define A_INDIRECT() A 

#define X(arg) arg 
#define Y(arg) X(arg) 
#define Z(arg) Y(arg) 

    A(0) // A_INDIRECT()(1) 
X(A(0)) // A_INDIRECT()(2) 
Y(A(0)) // A_INDIRECT()(3) 
Z(A(0)) // A_INDIRECT()(4) 

各呼び出しは、結果が毎回異なるようにさせるスキャンの異なる数、に供されます。

マクロはグローバルな状態に影響しません。何らかの状態を達成する他の唯一の方法は、再帰を使用することです。マクロは再帰的に展開されないので、プリプロセッサはこの状態のトラックを保持します。マクロによって影響を受ける唯一の「グローバル」状態です。しかし、制御が難しい場合があります。マクロは、レベルごとにマクロを使用して特定の再帰レベルで拡張する必要があります。また、「状態」を効率的に読み取るには、何らかのバイナリ検索が必要です。

関連する問題