2012-03-01 5 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

흠 ...이 경우 M (x)와 M (y)를 호출해야한다. 런타임에 작동합니다. 내 마르코스는 콜백 (callbacks)이기 때문에 호출 될 수 없다. 컴파일 시간에이 작업을 수행하는 방법은 무엇입니까? –

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)의 각 호출

결과 매번 다른되게 스캔의 다른 번호로 행한다.

매크로는 전역 상태에 영향을 줄 수 없습니다. 일종의 상태를 달성하는 유일한 방법은 재귀를 사용하는 것입니다. 매크로는 재귀 적으로 확장되지 않으므로 전처리 기는이 상태의 트랙을 유지합니다. 매크로에 의해 영향을받을 수있는 유일한 "전역"상태입니다. 그러나 제어하기가 어려울 수 있습니다. 매크로는 각 레벨마다 매크로를 사용하여 특정 재귀 수준에서 확장해야하며 "상태"를 효율적으로 읽으려면 이진 검색의 일부 양식이 필요합니다.