zhaozj2021-02-08  242

A few days ago, I saw such a discussion in the CBS Forum: How do I use variable parameters in the macro definition? ( 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:

// 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 (, even in CUJ C EXPERTS Forum can also see similar approach (, of course, AlexandRescu is stronger.

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



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


New Post(0)