I want to write a macro that produces debug output and has a variable
number of arguments, so that I can use like this:
int i;
char *s;
DBG("simple message\n");
DBG("message with an int argument, value is %d\n", i);
DBG("two arguments: int %d, strings %s\n", i, s);
The output should be a fixed prefix, say "DEBUG ", followed by the
function name the macros is used in, and then by the string passed to
the macro, including further arguments.
The best solution I have found so far, is
#define DBG(fmt, ...) printf("DEBUG %s:" fmt, __func__, __VA_ARGS__)
This works as intended as long as there is at least one argument
following the format strings, but it expands to
printf("DEBUG %s:" fmt, __func__,) when there is no argument and that
causes a syntax error.
The draft of C99 I have here, disallows to give no arguments for the
ellipsis ... as stated in 6.10.3:
[#4] If the identifier-list in the macro definition does not end
with an ellipsis, the number of arguments, including those
arguments consisting of no preprocessing tokens, in an invocation
of a function-like macro shall agree with the number of parameters
in the macro definition. Otherwise, there shall be more arguments
in the invocation than there are parameters in the macro
definition (excluding the ...). There shall exist a )
preprocessing token that terminates the invocation.
Is there a better way to write the DBG() macro to avoid this?
urs 15 14075
Urs Thuermann <ur*@isnogud.escape.de> writes: I want to write a macro that produces debug output and has a variable number of arguments, so that I can use like this:
int i; char *s;
DBG("simple message\n"); DBG("message with an int argument, value is %d\n", i); DBG("two arguments: int %d, strings %s\n", i, s);
The output should be a fixed prefix, say "DEBUG ", followed by the function name the macros is used in, and then by the string passed to the macro, including further arguments.
The best solution I have found so far, is
#define DBG(fmt, ...) printf("DEBUG %s:" fmt, __func__, __VA_ARGS__)
<SNIP> Is there a better way to write the DBG() macro to avoid this?
There was a related thread a couple of weeks ago:
<http://groups.google.co.uk/group/comp.lang.c/browse_frm/thread/ac0bda529a91d754/949239c624c9fe71?lnk=st&q=logging+group%3Acomp.lan g.c&rnum=3&hl=en#949239c624c9fe71>
This basically used a *function* instead of a macro. The logging
function accepts variadic arguments, and these can then be modified
and passed on to a varargs form of printf (e.g. vfprintf).
--
John Devereux
On 2006-03-27, John Devereux <jd******@THISdevereux.me.uk> wrote: Urs Thuermann <ur*@isnogud.escape.de> writes:
I want to write a macro that produces debug output and has a variable number of arguments, so that I can use like this:
int i; char *s;
DBG("simple message\n"); DBG("message with an int argument, value is %d\n", i); DBG("two arguments: int %d, strings %s\n", i, s);
The output should be a fixed prefix, say "DEBUG ", followed by the function name the macros is used in, and then by the string passed to the macro, including further arguments.
The best solution I have found so far, is
#define DBG(fmt, ...) printf("DEBUG %s:" fmt, __func__, __VA_ARGS__) <SNIP> Is there a better way to write the DBG() macro to avoid this?
There was a related thread a couple of weeks ago:
<http://groups.google.co.uk/group/comp.lang.c/browse_frm/thread/ac0bda529a91d754/949239c624c9fe71?lnk=st&q=logging+group%3Acomp.lan g.c&rnum=3&hl=en#949239c624c9fe71>
This basically used a *function* instead of a macro. The logging function accepts variadic arguments, and these can then be modified and passed on to a varargs form of printf (e.g. vfprintf).
One little thing you might consider at an early stage : have an
importance or category enum as the first/second parameter : very
useful for filtering/enabling/disabling runtime logging for different
subsets in a non trivial system. You might even use the function name
and have settings to enable/disable logging for the particular function.
> This works as intended as long as there is at least one argument following the format strings, but it expands to printf("DEBUG %s:" fmt, __func__,) when there is no argument and that causes a syntax error.
#define macroFunc(a,b,...) ( Func(a, b, ##__VA_ARGS__) )
John Devereux wrote: Urs Thuermann <ur*@isnogud.escape.de> writes:
I want to write a macro that produces debug output and has a variable number of arguments, so that I can use like this:
int i; char *s;
DBG("simple message\n"); DBG("message with an int argument, value is %d\n", i); DBG("two arguments: int %d, strings %s\n", i, s);
The output should be a fixed prefix, say "DEBUG ", followed by the function name the macros is used in, and then by the string passed to the macro, including further arguments.
The best solution I have found so far, is
#define DBG(fmt, ...) printf("DEBUG %s:" fmt, __func__, __VA_ARGS__) <SNIP> Is there a better way to write the DBG() macro to avoid this?
There was a related thread a couple of weeks ago:
<http://groups.google.co.uk/group/comp.lang.c/browse_frm/thread/ac0bda529a91d754/949239c624c9fe71?lnk=st&q=logging+group%3Acomp.lan g.c&rnum=3&hl=en#949239c624c9fe71>
This basically used a *function* instead of a macro. The logging function accepts variadic arguments, and these can then be modified and passed on to a varargs form of printf (e.g. vfprintf).
See this one too: http://groups.google.co.uk/group/com...d17634c1ed7065
--
==============
Not a pedant
==============
raxip schrieb: This works as intended as long as there is at least one argument following the format strings, but it expands to printf("DEBUG %s:" fmt, __func__,) when there is no argument and that causes a syntax error.
#define macroFunc(a,b,...) ( Func(a, b, ##__VA_ARGS__) )
This is "gcc-C".
It is not valid C99, though.
-Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Assumptions are wonderous creatures.
raxip wrote: Assumptions are wonderous creatures.
That's nice. What does it have to do with anything? See my .sig below
for valuable information.
Brian
--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
> That's nice. What does it have to do with anything? See my .sig below for valuable information.
Is this better?
raxip wrote: That's nice. What does it have to do with anything? See my .sig below for valuable information.
Is this better?
Somewhat. Where are the attributions (the who said what part)? I know
that Google puts them in if you use the correct Reply.
Brian
Michael Mair wrote: raxip schrieb:This works as intended as long as there is at least one argument following the format strings, but it expands to printf("DEBUG %s:" fmt, __func__,) when there is no argument and that causes a syntax error.
#define macroFunc(a,b,...) ( Func(a, b, ##__VA_ARGS__) )
This is "gcc-C". It is not valid C99, though.
I believe it can be valid C99 if the result of macroFunc(...) is
stringized, and __VA_ARGS__ is empty. (Of course, in that case, it's
useless and doesn't answer the question.)
As for the original question, I had taken a look at a non-GCC way of
writing ,##__VA_ARGS__ earlier. I don't recommend anyone actually use
this for hopefully obvious reasons, but in case anyone cares, here it
is. Please let me know if there are bugs in it (there may well be).
#include <stdio.h>
#define CONCAT(x, y) CONCAT_(x, y)
#define CONCAT_(x, y) x##y
#define ID(...) __VA_ARGS__
#define IFMULTIARG(if,then,else) \
CONCAT(IFMULTIARG_, IFMULTIARG_(if, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 0, ))(then,else)
#define IFMULTIARG_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
_20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
_30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
_40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
_60, _61, _62, _63, ...) _63
#define IFMULTIARG_0(then, else) else
#define IFMULTIARG_1(then, else) then
#define PROVIDE_SECOND_ARGUMENT(x, ...) \
CONCAT(IFMULTIARG(ID(__VA_ARGS__), INSERT_, ADD_), \
SECOND_ARGUMENT) (x, __VA_ARGS__)
#define ADD_SECOND_ARGUMENT(x, y) y, x
#define INSERT_SECOND_ARGUMENT(x, y, ...) y, x, __VA_ARGS__
#define DEBUG(...) printf("DEBUG %s: " \
PROVIDE_SECOND_ARGUMENT(__func__, __VA_ARGS__))
int main() {
DEBUG("1\n");
DEBUG("%d\n", 2);
DEBUG("%d %d\n", 1, 2);
}
Groovy hepcat Urs Thuermann was jivin' on 27 Mar 2006 15:34:46 +0200
in comp.lang.c.
variadic macros and and empty replacement for __VA_ARGS__'s a cool
scene! Dig it! I want to write a macro that produces debug output and has a variable number of arguments, so that I can use like this:
int i; char *s;
DBG("simple message\n"); DBG("message with an int argument, value is %d\n", i); DBG("two arguments: int %d, strings %s\n", i, s);
The output should be a fixed prefix, say "DEBUG ", followed by the function name the macros is used in, and then by the string passed to the macro, including further arguments.
I think this should work:
#define DBG(...) printf("DEBUG $s: ", __func__), printf(__VA_ARGS__)
--
Dig the even newer still, yet more improved, sig! http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
> I think this should work: #define DBG(...) printf("DEBUG $s: ", __func__), printf(__VA_ARGS__)
This is the first answer in this thread, which seems to understand my
post and solves the problem of inserting the __func__ between the fmt
and __VA_ARGS__ without having the ,) when __VA_ARGS__ is empty.
I wanted to avoid calling printf() twice, because I need this in the
linux kernel (with printk instead of printf) and I'd prefer it to be
atomic. Also, I can't make a function debug(char *name, char *fmt, ...)
and call printk() from there, because the linux kernel doesn't have
vprintk().
But I will follow your suggesstion and will do it like follows:
#ifdef DEBUG
int debug = 0;
#define DBG(...) (debug & 1 ? (printk(KERN_DEBUG "%s: ", __func__), \
printk(__VA_ARGS__)) : 0)
#else
#define DBG(...)
#endif
where KERN_DEBUG is a string constant defined in the linux kernel
sources.
urs
Couldn't you get rid of the int debug = 0 using this?:
#define DEBUG 1
#ifdef DEBUG
#define DBG(...) (DEBUG ? (printk(KERN_DEBUG "%s: ", __func__), \
printk(__VA_ARGS__)) : 0)
#else
#define DBG(...)
#endif
pemo wrote:
Urs Thuermann wrote: I think this should work:
#define DBG(...) printf("DEBUG $s: ", __func__), printf(__VA_ARGS__)
This is the first answer in this thread, which seems to understand my post and solves the problem of inserting the __func__ between the fmt and __VA_ARGS__ without having the ,) when __VA_ARGS__ is empty.
I wanted to avoid calling printf() twice, because I need this in the linux kernel (with printk instead of printf) and I'd prefer it to be atomic. Also, I can't make a function debug(char *name, char *fmt, ...) and call printk() from there, because the linux kernel doesn't have vprintk().
But I will follow your suggesstion and will do it like follows:
#ifdef DEBUG int debug = 0; #define DBG(...) (debug & 1 ? (printk(KERN_DEBUG "%s: ", __func__), \ printk(__VA_ARGS__)) : 0) #else #define DBG(...) #endif
where KERN_DEBUG is a string constant defined in the linux kernel sources.
Couldn't you get rid of the int debug = 0 using this?:
#define DEBUG 1
#ifdef DEBUG
#define DBG(...) (DEBUG ? (printk(KERN_DEBUG "%s: ", __func__), \
printk(__VA_ARGS__)) : 0)
#else
#define DBG(...)
#endif
"pemo" <us***********@gmail.com> writes: Couldn't you get rid of the int debug = 0 using this?:
#define DEBUG 1
#ifdef DEBUG #define DBG(...) (DEBUG ? (printk(KERN_DEBUG "%s: ", __func__), \ printk(__VA_ARGS__)) : 0) #else #define DBG(...) #endif
No, your code doesn't make sense.
In my code, debug is initialized to zero (i.e. no debug output) but
can be set at module load time. There are other debug macros, that
test for debug&2 and debug&4.
urs This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: jois.de.vivre |
last post by:
Hi,
I'm writing a C++ program that uses C style macros for debugging
purposes. I have code that looks something like this:
#define DEBUG(str, ...) Show(__FILE__, __LINE__, str, ##...
|
by: Augustus S.F.X Van Dusen |
last post by:
I have recently come across the following construction:
#define P_VAR(output, string, args...) \
fprintf (output, "This is "string"\n", ##args)
which can be invoked as follows:
int x = 1,...
|
by: Trent Buck |
last post by:
(Note: C99 supports variadic macros, but C89 does not.)
I'm pretty sure what I'm trying to do is impossible, but I'll ask here
in case I'm missing something.
I'm trying to define generic,...
|
by: Michael B Allen |
last post by:
If I define a variadic macro like say:
#define PRINT(fmt, ...) _myprintf(__FILE__ ": " fmt, __VA_ARGS__)
and I call this like:
PRINT("no args");
the preprocessor generates:
|
by: Thomas Carter |
last post by:
I understand that C99 supports variadic macros. However, is it not the
case that a variadic macro defined as
#define SAMPLE_MACRO(...) Bloody-blah
must take at least one argument? I would be...
|
by: Laurent Deniau |
last post by:
I was playing a bit with the preprocessor of gcc (4.1.1). The following
macros expand to:
#define A(...) __VA_ARGS__
#define B(x,...) __VA_ARGS__
A() -nothing, *no warning*
A(x) -x
...
|
by: Christof Warlich |
last post by:
Hi,
is there any way to access individual elements in the body
of a variadic macro? I only found __VA_ARGS__, which always
expands to the complete list.
Thanks for any help,
Christof
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: jfyes |
last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
|
by: ArrayDB |
last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
|
by: PapaRatzi |
last post by:
Hello,
I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
| |