可变宏和__VA_ARGS__的空替换 [英] variadic macros and and empty replacement for __VA_ARGS__

查看:83
本文介绍了可变宏和__VA_ARGS__的空替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个产生调试输出的宏,并且有一个变量

参数个数,所以我可以像这样使用:


int i;

char * s;


DBG(simple message\ n);

DBG("带有int参数的消息,值为%d \ n",i);

DBG(" two arguments:int%d,strings%s \ n",i,s);


输出应该是一个固定的前缀,比如说DEBUG,然后是使用宏的

函数名,然后由字符串传递给

宏,包括进一步的参数。


到目前为止我找到的最佳解决方案是


#define DBG(fmt,...)printf(" DEBUG%s:" fmt,__ func __,__ VA_ARGS__)


只要有,就可以按预期工作至少有一个参数

跟随格式字符串,但是当没有争论时它扩展为

printf(DEBUG%s:fmt,__ func__,) nt和那个

会导致语法错误。


我在这里的C99草案,不允许为
$ b $提供任何参数b省略号...如6.10.3所述:


[#4]如果宏定义中的标识符列表没有结束

with a省略号,参数的数量,包括那些没有预处理令牌的
参数,在调用中

的函数式宏应该与参数的数量一致宏定义中的$>
。否则,调用中的参数应该比宏

定义中的参数更多(不包括......)。应该存在a)

预处理令牌来终止调用。

是否有更好的方法来编写DBG()宏以避免这种情况?


urs

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

推荐答案

Urs Thuermann< ur*@isnogud.escape.de>写道:
Urs Thuermann <ur*@isnogud.escape.de> writes:
我想编写一个产生调试输出的宏,并且有一个变量的参数数量,这样我就可以像这样使用:

int i;
char * s;

DBG(simple message \ n);
DBG(带有int参数的消息,值为% d \ n",i);
DBG(两个参数:int%d,字符串%s \ n,i,s);

输出应该是固定前缀,说DEBUG,然后是使用宏的
函数名称,然后通过传递给宏的字符串,包括进一步的参数。
到目前为止我找到的最佳解决方案是

#define DBG(fmt,...)printf(DEBUG%s:" fmt,__ func __,__ VA_ARGS__)

< SNIP>是否有更好的方法来编写DBG()宏以避免这种情况?
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?



几周前有一个相关的线程:


< 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>


这基本上使用了*函数*而不是宏。日志记录

函数接受可变参数,然后可以将这些参数修改为
并传递给printf的varargs形式(例如vfprintf)。

-


John Devereux


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


2006-03-27,John Devereux< jd ** ****@THISdevereux.me.uk>写道:
On 2006-03-27, John Devereux <jd******@THISdevereux.me.uk> wrote:
Urs Thuermann< ur*@isnogud.escape.de>写道:
Urs Thuermann <ur*@isnogud.escape.de> writes:
我想编写一个产生调试输出的宏,并且有一个变量的参数数量,这样我就可以像这样使用:

int i;
char * s;

DBG(simple message \ n);
DBG(带有int参数的消息,值为% d \ n",i);
DBG(两个参数:int%d,字符串%s \ n,i,s);

输出应该是固定前缀,说DEBUG,然后是使用宏的
函数名称,然后通过传递给宏的字符串,包括进一步的参数。
到目前为止我找到的最佳解决方案是#define DBG(fmt,...)printf(" DEBUG%s:" fmt,__ func __,__ VA_ARGS __)
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>


<SNIP>

有没有更好的方法来编写DBG()宏以避免这种情况?
Is there a better way to write the DBG() macro to avoid this?



有一个相关的线程一对几周前:

< htt p://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>

这基本上使用了*函数*而不是宏。日志记录
函数接受可变参数,然后可以修改这些参数并传递给printf的varargs形式(例如vfprintf)。


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
,它就会按预期工作,但它会扩展为
printf(DEBUG%s:fmt,__ func __,)没有参数,
导致语法错误。
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__))



#define macroFunc(a,b,...) ( Func(a, b, ##__VA_ARGS__) )


这篇关于可变宏和__VA_ARGS__的空替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆