變長引數的 Tracer

2021-04-14 05:08:10 字數 2093 閱讀 9557

幾天前,在csdn論壇看到這麼一則討論:在巨集定義中怎麼使用可變引數?(http://expert.csdn.net/expert/topic/2925/2925165.xml)。樓主希望能定義這樣的macro:

#define fun1(a, b, ...)   fun2(__file__, __line__, a, b, ...)

我猜樓主是想寫trace,如果不能使用可變引數的macro,那麼就得像mfc那樣寫一堆trace macros:

// 取自 mfc 7.1 的 afx.h

// the following trace macros are provided for backward compatiblity

//  (they also take a fixed number of parameters which provides

//   some amount of extra error checking)

#define trace0(sz)               trace(_t("%s"), _t(sz))

#define trace1(sz, p1)           trace(_t(sz), p1)

#define trace2(sz, p1, p2)       trace(_t(sz), p1, p2)

#define trace3(sz, p1, p2, p3)   trace(_t(sz), p1, p2, p3)

太醜陋了!還好,c99標準支援variadic macros,在gcc中,可以這麼寫:

還可以順便列印檔案名和行號:

#define debug(format, ...)  do while (0)

但可惜visual c++ 7.1還不支援這項功能:( 不過我們在c++中至少可以繞彎解決,做到既能自動記錄檔名和行號,又能使用變長引數呼叫。這個辦法不是我獨創的,實際上atl的atltrace.h中就有它的實現(ctracefileandlineinfo class),我在code project也找到了相同的實現(http://www.codeproject.com/debug/location_trace.asp),甚至在cuj的c++ experts forum 也能看到相近的做法(http://www.cuj.com/documents/s=8250/cujcexp2106alexandr/),當然alexandrescu的辦法技巧性更強。

思路:寫乙個過載了 operator() 的class,令 trace 巨集返回該class的乙個object:

#include

#include

#ifndef ndebug  // debug mode

class tracer

void operator()

(const char* fmt, ...)

private:

// copy-ctor and operator=

tracer(const tracer&);

tracer& operator=(const tracer&);

private:

const char* file_;

int         line_;

};#define trace (tracer(__file__, __line__))

#else  // ndebug

#define trace (void)

#endif // ndebug

int main()

{#ifndef ndebug

tracer(__file__, __line__)("%x", 123);

#endif

這樣做是multithreading-safe的。g++ 3.3.1 / visual c++ 7.1 / borland c++ 5.5.1 通過。

變長引數的 Tracer

幾天前,在csdn論壇看到這麼一則討論 在巨集定義中怎麼使用可變引數?http expert.csdn.net expert topic 2925 2925165.xml 樓主希望能定義這樣的macro define fun1 a,b,fun2 file line a,b,我猜樓主是想寫trace,...

變長引數的 Tracer

幾天前,在csdn論壇看到這麼一則討論 在巨集定義中怎麼使用可變引數?http expert.csdn.net expert topic 2925 2925165.xml 樓主希望能定義這樣的macro define fun1 a,b,fun2 file line a,b,我猜樓主是想寫trace,...

變長引數的 Tracer

幾天前,在csdn論壇看到這麼一則討論 在巨集定義中怎麼使用可變引數?http expert.csdn.net expert topic 2925 2925165.xml 樓主希望能定義這樣的macro define fun1 a,b,fun2 file line a,b,我猜樓主是想寫trace,...