Tracer with Variable Length Parameters

Source: Internet
Author: User
Tags variadic

A few days ago, I saw this discussion on the csdn Forum: how to use variable parameters in macro definition? Http://expert.csdn.net/Expert/topic/2925/2925165.xml ). The owner hopes to define macro as follows:

# Define fun1 (a, B,...) fun2 (_ file __, _ line __, a, B ,...)

I guess the main idea is to write trace. If you cannot use macro with variable parameters, you have to write a bunch of Trace macros like MFC:

// Afx. h from MFC 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, the c99 standard supports variadic macros, which can be written in GCC as follows:

// 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 row number by the way:

# Define debug (format,...) do {/
Fprintf (stderr, "% s (% d):", _ file __, _ line __);/
Fprintf (stderr, format, _ va_args __);/
} While (0)

However, Visual C ++ 7.1 does not support this function yet: (however, we can at least bend around in C ++ to automatically record file names and row numbers, you can also use the variable length parameter. This method is not my original one. In fact, the atltrace of ATL. h has its implementation (ctracefileandlineinfo class), I found the same implementation (http://www.codeproject.com/debug/location_trace.asp) in the Code project ), even in cuj C ++ Experts Forum can also see similar practices (http://www.cuj.com/documents/s=8250/cujcexp2106alexandr/), of course, Alexandrescu approach more skillful.

Idea: Write a class with operator () reloaded, so that the trace macro returns an object of the class:

# 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 &);
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

Trace ("% s", "Happy debugging .");
}

This is done in multithreading-safe mode. G ++ 3.3.1/Visual C ++ 7.1/Borland C ++ 5.5.1.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.