C 函数中的变量参数
Variable arguments in C functions
我读过可变参数函数“int func(int, ...)
”。
这些函数的参数在哪里分配(堆栈或堆)?
因为我读到 va_end()
宏释放了分配给 va_list
的 space,所以 "frees" 这个词引起了我的注意。
注意:我知道常规函数会进入堆栈,但这种类型的函数很有趣,因为参数的数量是未知的。
我只想确定它不像没有预定义的数组space;
我们在最后使用 malloc()
和 free()
。
Link: https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm
c itself doesn't specify things like "heap" or "stack", so programming standard and portable c, you should better think in categories of the c标准:静态、自动和动态存储。
然而,在典型的实现中,"automatic storage" 转换为 "the stack is used for it"。函数参数就是这种情况,可变参数函数也不例外。
va_end()
可能会释放一些动态存储空间(通常:分配在堆上)的原因是 va_arg()
宏通常需要一些上下文信息来查找 next 参数。 va_start()
将为该信息(而不是参数本身)分配内存 并以某种方式对其进行初始化,以便第一个 va_arg()
调用 returns第一个可变参数。
请注意,va_start()
的实现 没有 分配内存。 va_list
的定义方式可能是为所需的上下文信息提供 space。但这对作为程序员的你来说 根本没有兴趣,所有 va_*
东西对你来说都是一个 黑匣子 如果文档说明 "call va_end()
when done for cleanup",你就照做 ;)
一般平台都有调用约定。前几个参数进入寄存器,随后的进入堆栈。这对 C 代码本身是故意不透明的。 va_start 和 va_end 提供了调用约定的包装器,允许您按索引而不是名称按顺序访问参数。
请注意,您无法在运行时构建 va_args 块。这是 C 不允许你做的少数事情之一。您只能通过调用变量 args 函数来生成块。
另请注意,实际上变量参数列表用于包装对 vsprintf() 的调用。您几乎永远不会发现它们在生产 C 代码中用于任何其他目的。
我读过可变参数函数“int func(int, ...)
”。
这些函数的参数在哪里分配(堆栈或堆)?
因为我读到 va_end()
宏释放了分配给 va_list
的 space,所以 "frees" 这个词引起了我的注意。
注意:我知道常规函数会进入堆栈,但这种类型的函数很有趣,因为参数的数量是未知的。
我只想确定它不像没有预定义的数组space;
我们在最后使用 malloc()
和 free()
。
Link: https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm
c itself doesn't specify things like "heap" or "stack", so programming standard and portable c, you should better think in categories of the c标准:静态、自动和动态存储。
然而,在典型的实现中,"automatic storage" 转换为 "the stack is used for it"。函数参数就是这种情况,可变参数函数也不例外。
va_end()
可能会释放一些动态存储空间(通常:分配在堆上)的原因是 va_arg()
宏通常需要一些上下文信息来查找 next 参数。 va_start()
将为该信息(而不是参数本身)分配内存 并以某种方式对其进行初始化,以便第一个 va_arg()
调用 returns第一个可变参数。
请注意,va_start()
的实现 没有 分配内存。 va_list
的定义方式可能是为所需的上下文信息提供 space。但这对作为程序员的你来说 根本没有兴趣,所有 va_*
东西对你来说都是一个 黑匣子 如果文档说明 "call va_end()
when done for cleanup",你就照做 ;)
一般平台都有调用约定。前几个参数进入寄存器,随后的进入堆栈。这对 C 代码本身是故意不透明的。 va_start 和 va_end 提供了调用约定的包装器,允许您按索引而不是名称按顺序访问参数。
请注意,您无法在运行时构建 va_args 块。这是 C 不允许你做的少数事情之一。您只能通过调用变量 args 函数来生成块。
另请注意,实际上变量参数列表用于包装对 vsprintf() 的调用。您几乎永远不会发现它们在生产 C 代码中用于任何其他目的。