如何在函数中传递不限制参数个数的参数?

时间:2022-07-25 18:00:07

It come across to me that function like printf() have not limited the number of parameters.

对我来说,像printf()这样的函数没有限制参数的数量。

But when debugging program on Solaris, I noticed it will push at most 5 parameters into stack, common register will be used if there are more than 5 parameters.

但是当在Solaris上调试程序时,我注意到它会将最多5个参数放入堆栈,如果有5个以上的参数,就会使用公共寄存器。

So what will happen if even common register is not enough in function like printf ? Did compiler do something for me ?

如果连公共寄存器都不能像printf那样在函数中充分发挥作用,会发生什么呢?编译器为我做了什么吗?

2 个解决方案

#1


4  

The behaviour is controlled by the ABI for the platform. If there are more parameters than fit in the registers, then they will be handled in a different way. There isn't a simple upper limit on the number of arguments that can be passed, so the compiler and the ABI define a mechanism that works on the hardware in question. What works on SPARC does not necessarily work on, for example, Intel IA32.

这种行为由该平台的ABI所控制。如果寄存器中有比适合的参数更多的参数,那么它们将以不同的方式处理。对于可以传递的参数的数量没有一个简单的上限,因此编译器和ABI定义了一种机制,可以在有问题的硬件上工作。在SPARC上工作的东西不一定适用于,例如,Intel IA32。

#2


0  

Normally platforms where the ABI uses registers for argument passing switch to a different calling convention for variadic functions, whereby everything is passed on the stack. This is why the C standard assigned undefined behavior to calling a variadic function without a prototype; without a prototype, on such platforms the compiler will generate an incorrect call.

通常情况下,ABI使用寄存器来传递参数,将变量函数转换为不同的调用约定,从而在堆栈上传递所有内容。这就是为什么C标准将未定义的行为分配给没有原型的变量函数;如果没有原型,编译器将在这样的平台上生成错误的调用。

It should be noted that some platforms use more complicated (uselessly complicated, I would say) methods of passing arguments to variadic functions, such as constructing a sort of linked list and passing a hidden pointer to that list, which the implementation of va_start is then somehow able to obtain. As a programmer, you should just treat the whole stdarg.h stuff as a black box that does what's expected, and pray that you never have to see the gorey details of some of the uglier implementations...

需要注意的是,有些平台使用更复杂的(可以说是无用的复杂)方法将参数传递给变量函数,比如构造一种链表并传递一个隐藏的指针到该列表,这样va_start的实现就可以获得该列表。作为一名程序员,你应该把所有的问题都解决掉。h的东西就像一个黑盒子,做着我们所期望的,祈祷你永远都不会看到一些更丑陋的实现的繁琐细节……

#1


4  

The behaviour is controlled by the ABI for the platform. If there are more parameters than fit in the registers, then they will be handled in a different way. There isn't a simple upper limit on the number of arguments that can be passed, so the compiler and the ABI define a mechanism that works on the hardware in question. What works on SPARC does not necessarily work on, for example, Intel IA32.

这种行为由该平台的ABI所控制。如果寄存器中有比适合的参数更多的参数,那么它们将以不同的方式处理。对于可以传递的参数的数量没有一个简单的上限,因此编译器和ABI定义了一种机制,可以在有问题的硬件上工作。在SPARC上工作的东西不一定适用于,例如,Intel IA32。

#2


0  

Normally platforms where the ABI uses registers for argument passing switch to a different calling convention for variadic functions, whereby everything is passed on the stack. This is why the C standard assigned undefined behavior to calling a variadic function without a prototype; without a prototype, on such platforms the compiler will generate an incorrect call.

通常情况下,ABI使用寄存器来传递参数,将变量函数转换为不同的调用约定,从而在堆栈上传递所有内容。这就是为什么C标准将未定义的行为分配给没有原型的变量函数;如果没有原型,编译器将在这样的平台上生成错误的调用。

It should be noted that some platforms use more complicated (uselessly complicated, I would say) methods of passing arguments to variadic functions, such as constructing a sort of linked list and passing a hidden pointer to that list, which the implementation of va_start is then somehow able to obtain. As a programmer, you should just treat the whole stdarg.h stuff as a black box that does what's expected, and pray that you never have to see the gorey details of some of the uglier implementations...

需要注意的是,有些平台使用更复杂的(可以说是无用的复杂)方法将参数传递给变量函数,比如构造一种链表并传递一个隐藏的指针到该列表,这样va_start的实现就可以获得该列表。作为一名程序员,你应该把所有的问题都解决掉。h的东西就像一个黑盒子,做着我们所期望的,祈祷你永远都不会看到一些更丑陋的实现的繁琐细节……