为什么无效F(...)不是在C允许? [英] Why is void f(...) not allowed in C?

查看:109
本文介绍了为什么无效F(...)不是在C允许?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 无效F(...)
{
    // 做一点事...
}


解决方案

我觉得对于可变参数的函数都必须有一个命名参数要求的动机是为的va_start 均匀。为了便于实施,的va_start 取最后命名参数的名称。在一个典型的可变参数调用约定,并根据方向参数存储,的va_arg 会发现在地址的第一个变量参数(安培; PARAMETER_NAME)+ 1 (first_vararg_type *)(安培; PARAMETER_NAME) - 1 ,加上或减去一些填充以确保对齐

我不认为有就是为什么语言的无法的支持可变参数没有命名的参数功能什么特别的原因。那里将必须的va_start 的用于这种功能的使用的另一种形式,这将必须直接从堆栈指针得到第一个可变参数(或者是迂腐帧指针,这实际上是价值堆栈指针对函数入口,因为在功能上code很可能已经转移,因为函数入口的SP)。这是可能的原则 - 任何实施应该有机会获得栈[*]不知何故,在一定程度上 - 但它可能是恼人的一些实施者。一旦你知道了可变参数调用约定,你通常可以实现 VA _ 宏没有任何其他特定于实现的知识,这将需要的的知道如何在获得直接调用的参数。我以前的宏已实施的可变参数,在仿真层,那将让我生气。

此外,还有的不是很多对于没有命名的参数可变参数功能的实际使用。有一个可变参数的函数来确定的类型和可变参数数量没有语言功能,所以被调用者必须知道的第一个可变参数的类型,反正以阅读。所以你还不如让它与一类命名的参数。在的printf 和朋友的第一个参数的值的通知功能什么的类型的是可变参数,以及如何许多人也有。

我想,在理论上被叫方可以考虑一下全球弄清楚如何读取第一个参数(是否有甚至是一个),但是这是pretty讨厌。我肯定不会去我的方式来支持,并加入的va_start 新版本的额外实施负担走出自己的路。

[*]或者如果实现不使用栈,到任何它使用的,而不是来传递函数参数。

Why doesn't C allow a function with variable length argument list such as:

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

解决方案

I think the motivation for the requirement that varargs functions must have a named parameter is for uniformity of va_start. For ease of implementation, va_start takes the name of the last named parameter. With a typical varargs calling convention, and depending on the direction arguments are stored, va_arg will find the first vararg at address (&parameter_name) + 1 or (first_vararg_type*)(&parameter_name) - 1, plus or minus some padding to ensure alignment.

I don't think there's any particular reason why the language couldn't support varargs functions with no named parameters. There would have to be an alternative form of va_start for use in such functions, that would have to get the first vararg directly from the stack pointer (or to be pedantic the frame pointer, which is in effect the value that the stack pointer had on function entry, since the code in the function might well have moved the sp since function entry). That's possible in principle -- any implementation should have access to the stack[*] somehow, at some level -- but it might be annoying for some implementers. Once you know the varargs calling convention you can generally implement the va_ macros without any other implementation-specific knowledge, and this would require also knowing how to get at the call arguments directly. I have implemented those varargs macros before, in an emulation layer, and it would have annoyed me.

Also, there's not a lot of practical use for a varargs function with no named parameters. There's no language feature for a varargs function to determine the type and number of variable arguments, so the callee has to know the type of the first vararg anyway in order to read it. So you might as well make it a named parameter with a type. In printf and friends the value of the first parameter tells the function what the types are of the varargs, and how many of them there are.

I suppose that in theory the callee could look at some global to figure out how to read the first argument (and whether there even is one), but that's pretty nasty. I would certainly not go out of my way to support that, and adding a new version of va_start with extra implementation burden is going out of my way.

[*] or if the implementation doesn't use a stack, to whatever it uses instead to pass function arguments.

这篇关于为什么无效F(...)不是在C允许?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆