可变宏的行为 [英] behavior of variadic macro

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

问题描述

我正在使用gcc(4.1.1)的预处理器。以下

宏扩展为:


#define A(...)__ VA_ARGS__

#define B(x,。 ..)__ VA_ARGS__


A() - 没什么,*没有警告*

A(x)-x


B() - 无,*警告ISO C99要求使用休息参数*

B(x) - 无,*警告ISO C99要求使用休息参数*

B(x,y)-y


虽然我同意gcc对B()的使用行为,但我感觉有点

混淆了它在A()上的行为,我期待同样的警告

和B()根据ISO C99 6.10.3p4:


[ ...]

调用中的参数应该多于宏定义中的

参数(不包括......)

>
这是更多参数吗?只有在至少需要一个参数时才适用

(不包括......)?


a +,ld。

解决方案

Laurent Deniau写道:


我正在使用gcc(4.1.1)的预处理器。以下

宏扩展为:


#define A(...)__ VA_ARGS__

#define B(x,。 ..)__ VA_ARGS__


A() - 没什么,*没有警告*
[...]

虽然我同意这个行为关于B()的使用gcc,我觉得有点

被它在A()上的行为搞糊涂了,我期待同样的警告

和B()一样到ISO C99 6.10.3p4:


[...]

调用中的参数应该多于

宏定义中的参数(不包括......)


这是更多参数吗?仅在至少需要一个参数

(不包括......)时才适用?



你给A()一个参数。那个论点是空洞的。它表现得好像你已经写了


#define EMPTY()/ *没有* /

#define A(。 ..)__ VA_ARGS__

#define B(x,...)__ VA_ARGS__

A(EMPTY())


同样,你可以写

B(x,)

表现为

B(x,EMPTY())

但不是

B(x)


(在一般情况下,你无法从宏调用告诉多少
$ b在没有看到它的定义的情况下传递$ b参数。对于EMPTY(),在上面示例的

中,没有传递参数。)


Harald van D?3k写道:


Laurent Deniau写道:


>>我正在使用gcc(4.1.1)的预处理器。以下
宏扩展为:

#define A(...)__ VA_ARGS__
#define B(x,...)__ VA_ARGS__

A() - 没什么,*没有警告*
[...]
虽然我同意gcc对B()的使用行为,但我感到有点困惑根据ISO C99 6.10.3p4,A()上的行为,我期待与B()相同的警告:

[...]
应该有更多调用中的参数比宏定义中的
参数(不包括......)

这是更多参数吗?仅在需要至少一个论点(不包括......)时适用?




你给A()一个参数。那个论点是空洞的。它表现得好像你已经写了


#define EMPTY()/ *没有* /

#define A(。 ..)__ VA_ARGS__

#define B(x,...)__ VA_ARGS__

A(EMPTY())



AFAIK,A(EMPTY())为A提供了一个参数,它扩展为无值

这与A()不完全不同,后者不给A提供参数。
< blockquote class =post_quotes>
同样地,你可以写

B(x,)

,表现为

B (x,EMPTY())



这与gcc所说的不一致(我同意的地方):


#define E()/ *没有* /


A() - / *没什么,没有警告,?? * /

A(E()) - / *没有,没有警告,OK * /

A(x)-x


B() - / *没什么,警告,OK * /

B(E()) - / *没什么,警告,OK * /

B( x) - / *没有,警告,OK * /

B(x,E()) - / *没有,没有警告,OK * /

B(x ,y)-y


OK表示我同意行为(包括诊断),而??

表示我期待约束的诊断违反。


(在一般情况下,你无法告诉宏调用多少

参数在没有看到它的定义的情况下传递。



奇怪,如果N <64,我有一个宏返回从0到N的宏接收的参数数量

。 br />

a +,ld。


Laurent Deniau写道:


Harald van D?3k写道:


Laurent Deniau写道:


>我正在使用gcc(4.1.1)的预处理器。以下
宏扩展为:

#define A(...)__ VA_ARGS__
#define B(x,...)__ VA_ARGS__

A() - 没什么,*没有警告*
[...]
虽然我同意gcc对B()的使用行为,但我感到有点困惑根据ISO C99 6.10.3p4,A()上的行为,我期待与B()相同的警告:

[...]
应该有更多调用中的参数比宏定义中的
参数(不包括......)

这是更多参数吗?仅在需要至少一个论点(不包括......)时适用?



你给A()一个参数。那个论点是空洞的。它表现得好像你已经写了


#define EMPTY()/ *没有* /

#define A(。 ..)__ VA_ARGS__

#define B(x,...)__ VA_ARGS__

A(EMPTY())



AFAIK,A(EMPTY())为A提供了一个参数,它扩展为无值

这与A()不完全不同,A()不给A提供参数。



在C90中可能就是这种情况(据我记得,这不是特别明确的b $ b),但它不是''在C99中的情况,如果您使用的是可变参数宏,则使用


同样,你可以写

B(x,)

表现为

B(x,EMPTY())



这与gcc所说的不一致(我同意的地方):



它是。


#define E()/ *没有* /


A() - / *没什么,没有警告,?? * /

A(E()) - / *没有,没有警告,OK * /

A(x)-x


B() - / *没什么,警告,OK * /

B(E()) - / *没什么,警告,OK * /

B( x) - / *没有,警告,OK * /



你在这里使用B(x)而不是B(x,)。有区别。


B(x,E()) - / *没有,没有警告,OK * /

B (x,y)-y


OK表示我同意行为(包括诊断),而??

表示我期待诊断约束违规。


(在一般情况下,你无法告诉宏调用多少

参数传递而没有看到它的定义。



奇怪,如果N <64,我有一个宏返回从0到N的宏接收的参数数量




我想看看它。它是否特别通过实际处理0的情况来测试
测试是否有参数是空的吗?


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

B() -nothing, *warning ISO C99 requires rest arguments to be used*
B(x) -nothing, *warning ISO C99 requires rest arguments to be used*
B(x,y) -y

While I agree with the behavior of gcc on the uses of B(), I feel a bit
confused by its behavior on A() where I was expecting the same warning
as for B() according to ISO C99 6.10.3p4:

[...]
there shall be more arguments in the invocation than there are
parameters in the macro definition (excluding the ...)

Does this "more arguments" apply only if at least one argument
(excluding the ...) is required?

a+, ld.

解决方案

Laurent Deniau wrote:

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*
[...]
While I agree with the behavior of gcc on the uses of B(), I feel a bit
confused by its behavior on A() where I was expecting the same warning
as for B() according to ISO C99 6.10.3p4:

[...]
there shall be more arguments in the invocation than there are
parameters in the macro definition (excluding the ...)

Does this "more arguments" apply only if at least one argument
(excluding the ...) is required?

You gave A() an argument. That argument was empty. It behaves as if you
had written

#define EMPTY() /* nothing */
#define A(...) __VA_ARGS__
#define B(x,...) __VA_ARGS__
A(EMPTY())

Similarly, you could write
B(x,)
which would behave as
B(x,EMPTY())
but not
B(x)

(In the general case, you cannot tell from a macro invocation how many
arguments are passed without seeing its definition. For EMPTY(), in the
above examples, no arguments are passed.)


Harald van D?3k wrote:

Laurent Deniau wrote:

>>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*
[...]
While I agree with the behavior of gcc on the uses of B(), I feel a bit
confused by its behavior on A() where I was expecting the same warning
as for B() according to ISO C99 6.10.3p4:

[...]
there shall be more arguments in the invocation than there are
parameters in the macro definition (excluding the ...)

Does this "more arguments" apply only if at least one argument
(excluding the ...) is required?



You gave A() an argument. That argument was empty. It behaves as if you
had written

#define EMPTY() /* nothing */
#define A(...) __VA_ARGS__
#define B(x,...) __VA_ARGS__
A(EMPTY())

AFAIK, A(EMPTY()) provides an argument to A which expands to nothing
which is quite different to A() which does not give an argument to A.

Similarly, you could write
B(x,)
which would behave as
B(x,EMPTY())

this is not consistent with what gcc says (and where I agree with it):

#define E() /* nothing */

A() -/* nothing, no warning, ?? */
A(E()) -/* nothing, no warning, OK */
A(x) -x

B() -/* nothing, warning, OK */
B(E()) -/* nothing, warning, OK */
B(x) -/* nothing, warning, OK */
B(x,E()) -/* nothing, no warning, OK */
B(x,y) -y

OK means I agree with the behavior (including the diagnostic) while ??
means that I am expecting the diagnostic of the constraint violation.

(In the general case, you cannot tell from a macro invocation how many
arguments are passed without seeing its definition.

Strange, I have a macro which returns the number of arguments received
by a macro from 0 to N if N < 64.

a+, ld.


Laurent Deniau wrote:

Harald van D?3k wrote:

Laurent Deniau wrote:

>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*
[...]
While I agree with the behavior of gcc on the uses of B(), I feel a bit
confused by its behavior on A() where I was expecting the same warning
as for B() according to ISO C99 6.10.3p4:

[...]
there shall be more arguments in the invocation than there are
parameters in the macro definition (excluding the ...)

Does this "more arguments" apply only if at least one argument
(excluding the ...) is required?


You gave A() an argument. That argument was empty. It behaves as if you
had written

#define EMPTY() /* nothing */
#define A(...) __VA_ARGS__
#define B(x,...) __VA_ARGS__
A(EMPTY())


AFAIK, A(EMPTY()) provides an argument to A which expands to nothing
which is quite different to A() which does not give an argument to A.

That may have been the case in C90 (from what I recall, it wasn''t
particularly clear on the subject), but it isn''t the case in C99, which
you are using if you''re using variadic macros.

Similarly, you could write
B(x,)
which would behave as
B(x,EMPTY())


this is not consistent with what gcc says (and where I agree with it):

It is.

#define E() /* nothing */

A() -/* nothing, no warning, ?? */
A(E()) -/* nothing, no warning, OK */
A(x) -x

B() -/* nothing, warning, OK */
B(E()) -/* nothing, warning, OK */
B(x) -/* nothing, warning, OK */

You''re using B(x) instead of B(x,) here. There''s a difference.

B(x,E()) -/* nothing, no warning, OK */
B(x,y) -y

OK means I agree with the behavior (including the diagnostic) while ??
means that I am expecting the diagnostic of the constraint violation.

(In the general case, you cannot tell from a macro invocation how many
arguments are passed without seeing its definition.


Strange, I have a macro which returns the number of arguments received
by a macro from 0 to N if N < 64.

I''d like to see it. Does it handle the case of 0 specially by actually
testing to see if the argument is empty?


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

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