views:

68

answers:

3

I am using the following way to cout a function's time:

#define TIME_COST(message, ...)\
 char szMessageBuffer[2048] = {0};\
 va_list ArgList;\
 va_start(ArgList, message);\
 vsprintf_s(szMessageBuffer, 2048, message, ArgList);\
 va_end(ArgList); \
 string strMessage(szMessageBuffer);\
 CQLogTimer t(strMessage);

// CQLogTimer is a self destructor,which will cout life time of its own and print szMessageBuffer. However when I use the macro this :

void fun
{
TIME_COST("hello->%s", filePath);
XXXXXX
}

The message generated always is hello->(null)

Can Any one help? Many thanks!

+1  A: 

Macros are not variadic functions, you don't need to process argument list with va_* functions. Macros just transform the text of the source code.

With that said, your compiler (MSVC I assume) supports variadic macros with __VA_ARGS__:

#define TIME_COST(fmt, ...)\
 char szMessageBuffer[2048] = {0};\
 sprintf_s(szMessageBuffer, 2048, fmt, __VA_ARGS__);\
 string strMessage(szMessageBuffer);\
 CQLogTimer t(strMessage);
Alex B
Assuming TIME_COST("hello->%s", filePath) call, your code wont compile - error C2664: 'int vswprintf_s(wchar_t *,size_t,const wchar_t *,va_list)' : cannot convert parameter 4 from '<type of the filePath parameter>' to 'va_list'
AOI Karasu
@AOI Karasu, yeah, missed that one.
Alex B
+3  A: 

The correct version is:

#define TIME_COST(message, ...)\
 char szMessageBuffer[2048] = {0};\
 sprintf_s(szMessageBuffer, 2048, message, __VA_ARGS__);\
 string strMessage(szMessageBuffer);\
 CQLogTimer t(strMessage);

__VA_ARGS__ is not va_list type, but comma-separated arguments, so you need to use sprintf_s, not vsprintf_s.

AOI Karasu
+2  A: 

A different approach to logging is to use streams:

#define LOG( msg )     \
  {                    \
     ostringstream os; \
     os << msg;        \
     CDLogTimer( os.str() ); \
  }

You can then say things like:

LOG( "the value of x is " << x << " and of y is " << y );
anon
I never liked this stream-style syntax and don't know why. Nevertheless your version looks much neater, than the one with sprintf_s.
AOI Karasu