2

マクロ展開を追跡したい - マクロが展開された回数と、展開が発生したときの引数は何ですか。

例えば、

次のようなマクロがあります。

#define mymacro(x) int x

私のコードでは、次のようなものがあります。

mymacro(a);
mymacro(b);

プリプロセッサ展開の最後に (特定のマクロを最後に展開する方法はありますか?)、mymacro が使用された回数と渡された引数を知りたいです。この場合、2 回になり、args は a と b になります。

ブーストプリプロセッサライブラリを調査していました。BOOST_PP_ARRAY がありますが、後で使用できるように「静的」にする方法がわかりません。

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

4

2 に答える 2

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";
    }
}
于 2012-03-01T07:57:26.583 に答える
0

最終的な目標が何であるかはよくわかりませんが、アクティブな引数を使用してスキャンの数 (拡張の数ではありません) を追跡できます。アクティブな引数は、プリプロセッサによってスキャンされるたびに展開されます。例えば、

#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)

A の呼び出しごとに異なる数のスキャンが行われるため、毎回結果が異なります。

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

于 2012-03-09T07:18:38.677 に答える