Archived

This topic is now archived and is closed to further replies.

macros and va_arg, va_list

This topic is 4982 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

Hi there, I''va made a very simple LogSystem, that can take multiple arguments, like printf() with "..." My problem is that I want to make a macro for calling the Log, because I want to simplify its use. Can anyone tell me how to represent the "..." argument in a macro that would call my printf-like function. Thanks.

Share this post


Link to post
Share on other sites
I''ve had the same problem.

if you use GCC, you can write stuff like:

#define DTC(bp...) printf(bp)

but unfortunately, this doesn''t work with VC++, and I don''t know if there is something similar.
if there is, I would be interested too

Share this post


Link to post
Share on other sites
well, I found that MACRO(...) printf(__VA_ARGS__) worked also, but one more time with GCC, but it is in the C99 specifications, and i''m pretty sure vc.net 2003 will respect this, I hope

Share this post


Link to post
Share on other sites
Take a look at how the TRACE macro works if you have access to MFC source.

or do

#define LOG printf

note no brackets in the macro.

This comes up all the time, do a search.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Share this post


Link to post
Share on other sites
droune2001, I believe you're looking for something like this?


int supercool_log_function(const char *fmt,...)
{
int cnt;
FILE *log = fopen("logfile.txt","r")
ap_list ap; // Varadic argument list.


// Set up the list (needs the parameter before the ...

// passed to it so it can find the stack).

va_start =(ap,fmt);

// vXprintf() functions work just like their Xprintf()

// counterparts but take an ap_list. Alternatively, if

// you wanted to get each argument yourself you can use

// (type) foo = va_arg(ap,(type)) repeatedly but you must

// ensure that your requesting the correct type and that

// you're requesting the right number of arguments, total.

cnt = vfprintf(log,fmt,ap);
va_end(ap);

fclose(log);
return (cnt);
}


Then you can call that just as you would any printf()-style function.

EDIT: Fixed fopen() call.


[edited by - jpetrie on April 22, 2004 10:48:07 AM]

Share this post


Link to post
Share on other sites
Thanks.
I will look into TRACE,that could be interesting.
The #define LOG printf is not exactly what I want... but if I have no solution, i could end up with it..

to jpetrie: I have already that kind of function.

What I wanted was to have some macro like ERROR_DBG("stuff %d", 3) that would call my log mynamespace::LogSystem:rint("stuff %d", 3, COLOR_RED, other things..). A macro that would take a const char * and a variable arg list, and would call my function adding some other parameters like the color of the text, depending on the macro I would use (warning_log, error_log, normal_log....).

Using the __VA_ARGS__ in a macro should work, but i''m not sure if Visual C++ recognize it...

Share this post


Link to post
Share on other sites
Why couldn't you just use normal functions?

void LOG_ERROR(char const* fmt, ...)
{
va_list args;
va_start (args, fmt);
MyGenericLog (COLOR_RED, oherstuff, fmt, args);
va_end (args);
}

You just have to change your logging function to accept a va_list instead of '...'

EDIT: Nothing important...
EDIT2: Or, to make writing and maintaining these functions easier:

#define CREATE_LOGGER(name,color,other) \
void name (char const* fmt, ...) \
{ \
va_list args; \
va_start (args, fmt); \
MyGenericLog ((color),(other),fmt,args); \
va_end (args); \
}

CREATE_LOGGER(LOG_WARNING, COLOR_ORANGE, other_warn)
CREATE_LOGGER(LOG_ERROR, COlOR_RED, other_err)

EDIT3: fixed formatting
[edited by - nonpop on April 22, 2004 11:21:50 AM]

[edited by - nonpop on April 22, 2004 11:28:10 AM]

[edited by - nonpop on April 22, 2004 11:31:53 AM]

Share this post


Link to post
Share on other sites
quote:
#define LOG printf


well, this would be useless.
but this:

#define LOG(format...) kr_log_printf(PV_MODULE_NAME, __FUNCTION__, __LINE__, __FILE__, format)

or something similar, wouldn''t, and I don''t really see how to do the same thing any other way... :|
that works...
but not with VC++ (oh, and btw, just tested the #define LOG(...) printf(__VA_ARGS__), it doesn''t work on .NET 2003)

Share this post


Link to post
Share on other sites
atm, I''ve got something like:

#define LOG_FORMAT(format) PV_MODULE_NAME, __FUNCTION__, format

and use it like:

kr_log_printf(LOG_FORMAT("hello %s\n"), "abcdef");

witch is a bit more annoying than just:

#define LOG(format...) kr_log_printf(PV_MODULE_NAME, __FUNCTION__, format);

and:

LOG("hello %s\n", "abcdef");

Share this post


Link to post
Share on other sites