纯粹是为了兴趣,我在......我不知道...... 15 - 20 年后重新学习 C。
我似乎记得变量参数是作为简单的宏实现的。
- 谁能记得他们是什么?
编辑:为了澄清我的问题,我知道它们与 va_list 等具有相同的名称,但是您还记得实际的宏定义吗?
- 他们今天还能工作吗?
纯粹是为了兴趣,我在......我不知道...... 15 - 20 年后重新学习 C。
我似乎记得变量参数是作为简单的宏实现的。
编辑:为了澄清我的问题,我知道它们与 va_list 等具有相同的名称,但是您还记得实际的宏定义吗?
您正在考虑 stdarg.h 中的va_list
、va_arg
、va_start
和va_end
(链接到 WP 文章)。他们仍然工作得很好。:-)
可变参数函数确实通常使用宏来实现。这些是标准化的 - 请参阅有关该主题的这篇维基百科文章。实际的宏定义取决于处理器架构,因为它们必须使用调用堆栈玩非便携式游戏。
即使在标准化之前,进行可变参数的方法也很常见。C89 标准给出了一个基于现有实践的标准化接口。这些做法的其余部分仍然存在,例如<varargs.h>
在 Unix98 中仍然存在:http ://www.opengroup.org/onlinepubs/007908799/xsh/varargs.h.html (但在当前版本中不再存在)
宏的实现总是非常依赖于系统(堆栈在两个方向上增长,甚至有系统使用链表作为堆栈,堆栈帧中各种事物的位置取决于处理器和通用约定,在某些处理器上-- Sparc 说 -- 首先需要保存寄存器,对齐要求可能会导致问题,...)
如果您想知道一个简单的实现是什么样的,这里有一个,取决于可能错误的假设(他们不会尝试正确对齐)并且即使假设成立,也肯定会失败一些极端情况:
typedef void* va_list;
#define va_start(va, arg) va = (void*)((&arg)+1)
#define va_arg(va, type) (va = (void*)(((type*)va) + 1), *((type*)va -1)
#define va_end(va)
今天的变量参数是通过中描述的接口完成的<stdarg.h>
——至于它们在 15 年前是如何完成的,我真的不能说。
很难说您从何时开始实施它们是否仍然有效,但是它们与其他人指出的几乎相同,它们只是移入了标准标题(标准是操作词)。
编译器作为内置扩展的内容取决于编译器,以及在调用它时传递给它的标志。
请记住,gcc不是唯一的 C 编译器,但它(与其他编译器一样)符合 c89 和 c99。