Introduction
Someone else has probably done this before, but I haven't seen it, so I had to make this up.
If you want to create a preprocessor macro that outputs something to a log, you generally want one that works something like this:
MYTRACE( "something something: %s (%d)", str, i );
It's a little tricky, because you want it to accept variable arguments, but I often see something like:
#define MYTRACE MyTrace
static inline MyTrace( const char* msg, ... )
{
}
__FILE__ and __LINE__
But, if you wanted MYTRACE to automatically put __FILE__ and __LINE__ into the trace message, you're stuck. You can't use them inside the MyTrace() function because __FILE__ and __LINE__ will always point to the header that defines it instead of the place you call MYTRACE -- and it isn't possible to have a vararg preprocessor macro.
If you're stubborn about such things, you do something like this:
#define MYTRACE1( m, a ) MyTrace( __FILE__, __LINE__, m, a )
#define MYTRACE2( m, a, b ) MyTrace( __FILE__, __LINE__, m, a, b )
#define MYTRACE3( m, a, b, c ) MyTrace( __FILE__, __LINE__, m, a, c )
(And so on). It's horrible to use, though, because you have to keep changing the macro you use when you add an argument.
A solution!
With a little imagination it's possible to work around this, though (at least in C++):
class tracing_output_debug_string
{
private:
const char* m_file;
int m_line;
enum { MY_BUFFER_SIZE = 1024 };
public:
tracing_output_debug_string( const char* file, int line ) :
m_file( file ),
m_line( line )
{
}
void operator()( const char* Format, ... )
{
}
};
#define MYTRACE (tracing_output_debug_string( __FILE__, __LINE__ ))
The downloadable project has an implementation (which writes to ::OutputDebugString()) in a .h file and a little test that shows it, you know, actually works.
I've only tried it on VS.NET (that's what I have), but I'm sure it would work on ... well, just about anything, really.