Tracer

zhaozj2021-02-08  612

A few days ago, I saw such a discussion in the CBS Forum: How do I use variable parameters in the macro definition? (http://expert.cbs.net/expert/topic/2925/2925165.xml). The landlord hopes to define such macro:

#define fun1 (a, b, ...) fun2 (__ file__, __line__, a, b, ...)

I guess the landlord wants to write TRACE. If you can't use the macro of the variable parameters, you have to write a bunch of Trace Macros like MFC:

From the MFC afx.h 7.1 // // 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)

Too ugly! Fortunately, C99 standard supports Variadic Macros, in GCC, you can write this:

// http://gcc.gnu.org/onlinedocs/gcc/variadic-macros.html#define debug (format, ...) fprintf (stderr, format, __va_args__)

You can also print the file name and the line number by following:

#define debug (Format, ...) DO {/ fprintf (stderr, "% s (% d):", __file__, __line __); / fprintf (stderr, format, __va_args __); /} while (0)

But unfortunately, Visual C 7.1 does not support this feature: (However, we can do at least around C , do both automatically record file names and line numbers, but also use viable parameters call. This approach is not my original, actual There is a CTRACEFILINFO CLASS in ATLTrace.h, I also found the same implementation in Code Project (http://www.codeproject.com/debug/location_trace.asp), even in CUJ C EXPERTS Forum can also see similar approach (http://www.cuj.com/documents/s=8250/cujcexp2106alexandr/), of course, AlexandRescu is stronger.

Idea: Write a class overloaded Operator (), let the Trace macro return to the Class of the Class Object:

#include

#include

#ifndef ndebug // debug mode

Class Tracer {public: Tracer (const char * file, int line): File_ (file), line_ (line) {} void operator () (const char * fmt, ...) {va_list ap; // print the file Name and Line Number Fprintf (stderr, "% s (% d):", file_, line_); va_start (ap, fmt); vfprintf (stderr, fmt, AP); VA_END (AP); fprintf (stderr, "/ R / N "); // print the new-line character} private: // copy-ctor and operator = tracer = (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

Trace ("% s", "happy debugging.");

This is Multithreading-Safe. G 3.3.1 / Visual C 7.1 / Borland C 5.5.1.

转载请注明原文地址:https://www.9cbs.com/read-91.html

New Post(0)