美文网首页Swift-Li
预编译计算一个可变参数列表的长度

预编译计算一个可变参数列表的长度

作者: Stark_Dylan | 来源:发表于2015-07-03 20:44 被阅读597次

看到这个问题, 第一反应就是用参数列表的api,va_start va_arg va_end遍历一遍计算个和,但仔细想想,对于可变参数这个事,在编译前其实就已经确定了,代码里括号里有多少个参数一目了然.

RAC中Racmetamarcos.h中就有一系列宏来完成这件事,硬是在预处理之后就拿到了可变参数个数:

首先看一下定义

#define metamacro_argcount(...) \ 
    metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 

这个宏由几个工具宏一层层展开,现在模拟一下展开过程:

  1. 假如我们要计算的如下:
int count = metamacro_argcount(a, b, c); 
  1. 于是乎第一层展开后:
int count = metamacro_at(20, a, b, c, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 

3.再看metamacro_at的定义:

#define metamacro_at(N, ...) metamacro_concat(metamacro_at, N)(__VA_ARGS__) 
// 下面是metamacro_concat做的事(简写一层) 
#define metamacro_concat_(A, B) A ## B 
  1. 于是乎第二层展开后:
int count = metamacro_at20(a, b, c, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); 

5.再看metamacro_at20这个宏干的事儿:

#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) 

6.于是乎第三层展开后,相当于截断了前20个参数,留下剩下几个:

int count = metamacro_head(3, 2, 1); 

7.这个metamacro_head:

#define metamacro_head(...) metamacro_head_(__VA_ARGS__, 0) 
#define metamacro_head_(FIRST, ...) FIRST 

8.后面加个0,然后取参数列表第一个,于是乎:

int count = 3; 

这样带来的好处不止是将计算在预处理时搞定,不拖延到运行时恶心cpu;但更重要的是编译检查。比如某些可变参数的实现要求可以填2个参数,可以填3个参数,其他的都不行,这样,也只有这样的宏的实现,才能在编译前就确定了错误。'

细节很重要。 @Dylan.

原文链接

相关文章

  • 预编译计算一个可变参数列表的长度

    看到这个问题, 第一反应就是用参数列表的api,va_start va_arg va_end遍历一遍计算个和,但仔...

  • Java语法糖之可变长度参数

    可变长度参数原理 反编译class文件: 可变长度参数只能作为方法中的最后一个参数,而且只能有一个。 总结 Jav...

  • java反射调用可变长度参数的方法

    在java中可以用可变长度参数,这样可以给调用者更大的灵活度,可变长度参数在编译后就是一个数组参数,不用担心可变长...

  • 可变参数列表

    可变参数列表 数组可以向可变参数传值,反之,不行 可变参数列表作为参数时只能放在参数的最后面 可变参数列表的方法是...

  • JavaSE进阶十一 反射机制二

    1,可变长度参数 语法:类型... (注意:一定是3个点) 可变长度参数要求参数个数是:0-N个。 可变长度参数在...

  • 【Python】Arg and kwargs

    *args **kwargs 变长参数。Python支持可变长度的参数列表,可以通过在函数定义的时候使用args和...

  • Go语言可变参数

    可变参数 参数数量可变的函数称为可变参数函数 在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符...

  • golang学习笔记之-函数可变参数

    语法 注意点: 如果函数的参数是可变参数,同时还有其他的参数。可变参数要放在形参列表的最后 一个函数的参数列表中,...

  • day6 list列表及其操作

    1.什么是列表(list) 列表是Python提供的容器型数据类型可变-列表中的每个元素的值可变,列表的长度可变,...

  • R语言技巧每日分享day6-对列表元素执行可变长参数函数do.c

    do.call()用于将list里面的每一个元素执行可变长参数函数。 首先可变长参数函数是指,函数参数的长度是可变...

网友评论

本文标题:预编译计算一个可变参数列表的长度

本文链接:https://www.haomeiwen.com/subject/tbryqttx.html