在C ++中,可变参数函数(那些在参数列表末尾带有...的函数)是否必须遵循__cdecl调用约定? [英] In C++, do variadic functions (those with ... at the end of the parameter list) necessarily follow the __cdecl calling convention?

查看:155
本文介绍了在C ++中,可变参数函数(那些在参数列表末尾带有...的函数)是否必须遵循__cdecl调用约定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道__stdcall函数不能有省略号,但是我想确保除__cdecl或__stdcall之外,没有平台支持stdarg.h函数来调用约定.

I know that __stdcall functions can't have ellipses, but I want to be sure there are no platforms that support the stdarg.h functions for calling conventions other than __cdecl or __stdcall.

推荐答案

调用约定必须是调用者从堆栈中清除参数的一种约定(因为被调用者不知道将传递什么).

The calling convention has to be one where the caller clears the arguments from the stack (because the callee doesn't know what will be passed).

尽管不一定与Microsoft所说的"__cdecl"相对应.举例来说,在SPARC上,它通常会在寄存器中传递参数,因为这是SPARC设计的工作方式-如果调用的深度足够深,其寄存器就基本上充当了调用堆栈,并溢出到主内存中他们将不再适合注册.

That doesn't necessarily correspond to what Microsoft calls "__cdecl" though. Just for example, on a SPARC, it'll normally pass the arguments in registers, because that's how the SPARC is designed to work -- its registers basically act as a call stack that gets spilled to main memory if the calls get deep enough that they won't fit into register anymore.

尽管我不太确定,但我希望在IA64(Itanium)上大致相同-它也有一个巨大的寄存器集(如果有内存,则有数百个).如果我没记错的话,那么您对寄存器的使用方式会有所宽容,但我希望至少在很多时候都可以类似地使用它.

Though I'm less certain about it, I'd expect roughly the same on IA64 (Itanium) -- it also has a huge register set (a couple hundred if memory serves). If I'm not mistaken, it's a bit more permissive about how you use the registers, but I'd expect it to be used similarly at least a lot of the time.

为什么这对您很重要?使用stdarg.h及其宏的目的在于隐藏代码调用约定中的差异,因此它可以可移植地与可变参数一起使用.

Why does this matter to you? The point of using stdarg.h and its macros is to hide differences in calling convention from your code, so it can work with variable arguments portably.

根据评论进行好的,现在我了解您在做什么(至少足以改善答案).假定您已经(显然)已经具有处理默认ABI中的变体的代码,那么事情就更简单了.剩下的问题是,可变参数函数是否始终使用默认ABI",无论手头上的平台是什么.使用"stdcall"和"default"作为唯一选项,我认为答案是肯定的.例如,在Windows上,wsprintfwprintf打破了经验法则,并使用cdecl调用约定而不是stdcall.

Edit, based on comments: Okay, now I understand what you're doing (at least enough to improve the answer). Given that you already (apparently) have code to handle the variations in the default ABI, things are simpler. That only leaves the question of whether variadic functions always use the "default ABI", whatever that happens to be for the platform at hand. With "stdcall" and "default" as the only options, I think the answer to that is yes. Just for example, on Windows, wsprintf and wprintf break the rule of thumb, and uses cdecl calling convention instead of stdcall.

这篇关于在C ++中,可变参数函数(那些在参数列表末尾带有...的函数)是否必须遵循__cdecl调用约定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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