Sign in to follow this  

Variadic Macros

This topic is 4666 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Does Visual C++ not support them or what? And if not, how might I go about converting the following code into something that it won't choke on without needing to rewrite a bunch of code?
void debugMessageHelper(const char *file, const char *function, int line, const char *message, ...) __attribute__ ((format (printf, 4, 5)));

#define debugMessage(FORMAT...) debugMessageHelper(__FILE__, __FUNCTION__, __LINE__, FORMAT)

Share this post


Link to post
Share on other sites
Assuming VC doesn't support them, you could do something like what mmgr does:

void recordDebugInfo(const char *file, const char *function, int line)
{
// Save as globals or something
}

void debugMessageHelper(const char *message, ...)
{
// Get file, function and line from saved variables
// ...
}
#define debugMessage recordDebugInfo(__FILE__, __FUNCTION__, __LINE__),debugMessageHelper


I've no idea what that __atribute__ does, I'm not a GCC person. I'm also not convinced I used the comma operator correctly - It's there so you can do something like if(bSomething) debugMessage("%d",42); since it's now in two function calls.

Share this post


Link to post
Share on other sites
The attribute bit there is so that GCC will treat it like printf, and yell at me if I write something that makes no sense like debugMessage("cheese %d", "foo", 42);

The comma operator seems like a good idea, except debugMessage is used in multiple threads, so storing it in globals would therefore be bad.

Share this post


Link to post
Share on other sites
That can still be solved with a minor modification.
struct debugContext {
debugContext(const char *file, int line) { }
void message(const char *format, ...) { }
};

#define debugMessage debugContext(__FILE__, __LINE__).message

Share this post


Link to post
Share on other sites
This is a bit ugly, but it should work if you can't find anything else:

//
// Header
//
class CInit
{
CRITICAL_SECTION* m_pcs;
public:
CInit(CRITICAL_SECTION* pcs) : m_pcs(pcs) {InitializeCriticalSection(pcs);}
~CInit() {DeleteCriticalSection(m_pcs);}
};

void recordDebugInfo(const char *file, const char *function, int line);
void debugMessageHelper(const char *message, ...);
#define debugMessage recordDebugInfo(__FILE__, __FUNCTION__, __LINE__),debugMessageHelper

//
// Source
//
CRITICAL_SECTION g_cs;
CInit(&g_cs);
const char* g_szFile;
const char* g_szFunction
int g_nLine;
void recordDebugInfo(const char *file, const char *function, int line)
{
EnterCriticalSection(&g_cs);
g_szFile = file;
g_szFunction = function;
g_nLine = line;
}

void debugMessageHelper(const char *message, ...)
{
// Do whatever you want to log here, and use the globals above

LeaveCriticalSection(&g_cs);
}




Edit: Too late. doynax's method is considerably better [smile]

Share this post


Link to post
Share on other sites

This topic is 4666 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this