Advertisement

#define x(a, b, c, ...) and va_list

Started by June 05, 2001 11:13 AM
10 comments, last by Harvester 23 years, 8 months ago
Can i use va_list within a #define statement? I searched through the MS definitions (on _ASSERT, etc...), and i noticed that they have made some kind of workarounds regarding va_list in defines. Anyone has any suggestions? note: i deal the same problem they seem to have dealt with on the _ASSERT def. I would modify and use _ASSERT, but by logging/debugging stuff(interfaces, etc...) reside within classes (that each object inherits, blablabla...) My goal is to use the __LINE__ and __FILE__ macros, but withought having to supply ''em to my ErrorReporting functions. (and unless i do it with #defines or inline, i''ll have to supply ''em each time.). I''m open to ideas. p.s. not that its really bugging me... just for the sake of clarity .
... LEMMINGS ... LEMMINGS ... LEMMINGS ... LEM..... SpLaSh!...Could this be what we stand like before the mighty One?Are we LeMmIngS or WhAt!? ;)
No you can''t use a variable number of arguments in a #define. You can do it in an inline function though - another good reason why inline functions are better that #define''s.

One trick for getting a similiar effect is to use double parens. e.g.:
#define DebugOut(x)  printf xvoid foo(){    int x = 3;    DebugOut(("x is %d\n", x));   // note double parens} 

-Mike
Advertisement
If you're talking about using va_list itself, then, yes, it's completely possible and straightforward.

But, I think you're asking how to do variable arguments with preprocessor macros. To my knowledge, there are ways to accomplish this, but they're all hacks--and this means that portability is basically thrown out the window.

Are you trying to implement an assert-like function? If so, you could try something like this, assuming that you haven't explicitly discounted this possiblity:

    void ___Assert(int exp, char* exp_str, char* file_name, int line){    if(!exp)    {        // stuff to generate an appropriate message        exit(0);    }}// and in some header file:/* this will make Assert do nothing in a release build, but check the expression in a debug build */#if defined(NDEBUG)#    define Assert(exp)#else#    define Assert(exp) ___Assert(exp, #exp, __FILE__, __LINE__)#endif // NDEBUG defined  



Edited by - merlin9x9 on June 5, 2001 5:49:40 PM
indeed inlines could do the trick, but what are the diferences between inline functions, and defines?
In both cases, what it does is something like... placing the code within the function, where it finds its name. Some sort of a shortcut that is.

So, what is the diference between #define x() (), and an inline adequate?

Could it be that with inline, it may place the function''s code, but still use the calling conversion protocol?


anyone knows?
... LEMMINGS ... LEMMINGS ... LEMMINGS ... LEM..... SpLaSh!...Could this be what we stand like before the mighty One?Are we LeMmIngS or WhAt!? ;)
If you put __LINE__ or __FILE__ in the inline function, it will always return the line and file of the inline function, and not where it was called from. Macros are useful for exactly what you want to do, because the compiler sees them at the point of call. But, as you point out, you can''t give a macro multiple parameters. The set of parameters (demonstrated in the double parentheses post above) as a parameter is probably the best way around this.

Resist Windows XP''s Invasive Production Activation Technology!
http://druidgames.cjb.net/ (If my website isn''t down, it''s a miracle!)
For the person who wanted to know the difference between macros and inline functions:

Macros are dealt with by the proprocessor. If you define a macro, each time you use that macro in your code the preprocessor cuts it out and replaces it with the macro body, then the compiler sees it and compiles it.

Inline functions are handled by the compiler itself, so it knows how to deal with them.

The real trouble occurs because of how variables are passed. In C and C++, they''re pushed on the runtime stack then the function is called, and the function uses them off the stack. WIth macros, and inlines, there is no function call and thus no stack frame. I''m not certain, but my guess is that for inline functions the compiler is smart enough to recognise that the inline function uses a variable argument list and pushes the arguments onto the stack then pastes in the function body. The argument routines themselves then peel the appropriate values off the stack for you to use. It can''t do this for macros because they all disappear before the compiler even gets to see it, so it has no idea that the body uses the variable argument lists.

I''m not 100% sure that is how it handles inline functions with variable argument lists, some compilers might just silently ignore the inline directive and do a real function call, or provide an error or warning message.
Advertisement
Most compilers will silently make inline functions non-inline under a number of complicating circumstances. MSVC ignores the majority of inline functions, and makes them work like normal. It ignores ALL inline functions that don''t use "__inline" until you change a project setting to allow "inline" functions as well.

Resist Windows XP''s Invasive Production Activation Technology!
http://druidgames.cjb.net/ (If my website isn''t down, it''s a miracle!)
Just a FYI...

The current C and C++ standards do not provide for variable argument preprocessor macros. HOWEVER, the upcoming C standard will allow this. I don''t expect too many compilers currently support this yet. (Possibly gcc, but definitely not MSVC.)
GCC already supports variable argument macros.
quote:

The current C and C++ standards do not provide for variable argument preprocessor macros. HOWEVER, the upcoming C standard will allow this. I don''t expect too many compilers currently support this yet. (Possibly gcc, but definitely not MSVC.)




Is there any place where these standards can be found online?
... LEMMINGS ... LEMMINGS ... LEMMINGS ... LEM..... SpLaSh!...Could this be what we stand like before the mighty One?Are we LeMmIngS or WhAt!? ;)

This topic is closed to new replies.

Advertisement