2012-03-01 3 views
2

Я хочу отслеживать расширение макросов - сколько раз расширялся макрос и какие аргументы возникают при расширении.Следите за расширением макроса

Например,

У меня есть макрос может выглядеть следующим образом:

#define mymacro(x) int x 

и в моем коде у меня есть что-то вроде этого:

mymacro(a); 
mymacro(b); 

в конце препроцессора расширение (о да, есть ли способ сделать конкретный макрос, чтобы стать последним, чтобы расширить?), я хотел бы знать, сколько раз использовался mymacro и какие аргументы передавались. В этом случае это будет 2 раза, а args - a и b.

Я изучал boost-preprocessor 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

Я не совсем уверен, что ваша конечная цель есть, но вы можете отслеживать количество сканирований (не количество расширений), используя активный аргумент. Активный аргумент расширяется каждый раз, когда он проверяется препроцессором. Например,

#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 подвергается различным числом сканирований, что приводит к тому, что результаты будут отличаться каждый раз.

Макросы не могут влиять на глобальное состояние. Единственный способ добиться своего состояния - использовать рекурсию. Помните, что макросы не рекурсивно расширяются, поэтому препроцессор сохраняет дорожки этого состояния. Его единственное «глобальное» состояние, на которое могут влиять макросы. Тем не менее, это может быть трудно контролировать. Макросы должны быть вынуждены расширяться с определенным уровнем рекурсии с помощью макроса для каждого уровня, и для получения «состояния» требуется некоторая форма бинарного поиска.

Смежные вопросы