#### Archived

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

# macros and va_arg, va_list

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

## 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 on other sites

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 on other sites
Thanks or the DTC tip, but my problem is that I mainly use VC++
I''m sure there is a solution... lot''s of people make LogFiles and macros.

##### 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 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 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 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 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 on other sites
Yeah!
nonpop your idea seems good to me.
Thx very much.

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

• 10
• 14
• 11
• 10
• 11