这个C宏是什么意思?

时间:2016-01-11 01:51:09

标签: c macros

这是一个宏可以计算参数的数量。和代码如:

#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args
#define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0

#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))

// the running result ---------------------------------------

MPL_ARGS_SIZE(a,b,c,d,e,f,g)==7

MPL_ARGS_SIZE(a,b,c,d)==4

如何理解

#define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0

Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX

BTW,我知道##(磅,磅)的用法和#define的机制Y_TUPLE_SIZE_I

1 个答案:

答案 0 :(得分:2)

PREFIX和POSTFIX宏旨在使其在没有给出参数时给出0,即MPL_ARGS_SIZE()。在这种情况下,Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX会连接起来生成Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX,这会强制结果为0.

在一般情况下,__VA_ARGS__非空,因此连接只会扩展为给定的相同数量的参数。接下来是32,... 0。

在这两种情况下,参数都包含在括号中。 Y_TUPLE_SIZE_II剥离这些额外的括号并将参数传递给Y_TUPLE_SIZE_IY_TUPLE_SIZE_I只是扩展到第33个参数,丢弃其余部分。

因此,如果你给它32个参数,那么将跳过那些32,并且根据需要,它们之后的数字32将是结果。如果你给它31个参数,它将跳过那31个,然后是第一个数字,即32,结果将是下一个数字31,再次根据需要。

如果你给它一个参数,它将跳过该参数和它后面的31,结果将是1.

如果你没有给它任何参数,那么Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX的特殊情况就会发挥作用,这是32个空参数后跟0。将跳过32个空参数,结果将为0。

没有参数的特殊情况的原因是没有参数,它的行为与单参数情况相同。以下内容可能有助于更好地理解它:

#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args
#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((__VA_ARGS__,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))

这是原始的宏集,但删除了零参数的所有特殊情况处理。它适用于除零参数情况之外的所有情况,它返回1而不是0。

为了处理零参数,它将前缀和后缀宏之间的争论列表夹在中间。如果结果扩展为Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX,则参数列表为空,并且特殊情况起作用。