gpt4 book ai didi

c - 为什么在 C 中不允许使用 void f(...)?

转载 作者:太空狗 更新时间:2023-10-29 17:15:40 26 4
gpt4 key购买 nike

为什么 C 不允许具有可变长度参数列表的函数,例如:

void f(...)
{
// do something...
}

最佳答案

我认为要求可变参数函数必须具有命名参数的动机是为了 va_start 的统一性。为了便于实现,va_start 采用最后一个命名参数的名称。使用典型的可变参数调用约定,并根据存储的方向参数,va_arg 将在地址 (&parameter_name) + 1(first_vararg_type* )(&parameter_name) - 1,加上或减去一些填充以确保对齐。

我认为语言不能支持不带命名参数的可变参数函数没有任何特别的原因。必须有一种替代形式的 va_start 用于此类函数,它必须直接从堆栈指针获取第一个可变参数(或者迂腐的帧指针,这实际上是堆栈指针在函数入口处的值,因为函数中的代码很可能在函数入口后移动了 sp)。这在原则上是可能的——任何实现都应该在某种程度上以某种方式访问​​堆栈[*]——但对于一些实现者来说这可能很烦人。一旦了解可变参数调用约定,通常无需任何其他特定于实现的知识即可实现 va_ 宏,这需要知道如何直接获取调用参数.我之前在仿真层中实现了那些可变参数宏,这会让我很恼火。

此外,没有命名参数的可变参数函数没有太多实际用途。可变参数函数没有语言特性来确定可变参数的类型和数量,因此被调用者无论如何都必须知道第一个可变参数的类型才能读取它。所以你不妨把它做成一个有类型的命名参数。在 printf 和 friend 中,第一个参数的 告诉函数可变参数的类型 是什么,以及它们有多少。

我想理论上被调用者可以查看一些全局变量来弄清楚如何读取第一个参数(以及是否有一个参数),但这非常讨厌。我当然不会特意支持它,添加新版本的 va_start 会增加额外的实现负担是我的做法。

[*] 或者如果实现不使用堆栈,则无论它使用什么来传递函数参数。

关于c - 为什么在 C 中不允许使用 void f(...)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6570447/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com