C编译器如何使用可变数量的参数实现函数?

Dan*_*Dan 13 c variables arguments

几天前我参加了一次技术面试,有人问我C编译器的implments如何使用可变数量的参数?它是如何通过堆栈的?

有谁知道或可以探索那个?

谢谢,丹

sta*_*ica 10

据我所知,用C ......

  • 调用函数按从右到左的顺序将参数压入堆栈.

  • 调用者负责在执行被调用函数后从堆栈中删除参数.这可能正是因为调用者保证知道它放在堆栈上的参数多少,而被调用的函数可能会错误.


PS: 调用约定通常是特定于实现的.我刚刚描述的内容被称为"cdecl"调用约定.将此与通常称为"stdcall"的调用约定进行对比,其中被调用函数负责从堆栈中删除其参数.因此,它不支持可变长度参数列表.


PPS:正如用户nategoose评论的那样,我没有提到实际使用的变量参数列表.有关详细信息,请参阅标题POSIX文档<stdarg.h>.

  • 这很清楚,但是你忽略了被调用者的角色.被调用者(例如printf)必须使用一个或多个必需参数(如格式字符串)来知道堆栈上的参数应该是什么.然后它使用目标特定的宏来访问那些作为数组(系统堆栈是一个可以移动头部的数组).stdarg.h头文件包含你需要执行此操作的宏,并且通常通常将指向此数组头部的指针传递给期望在其上工作的函数(如vprintf). (2认同)

小智 7

它使用va_宏实现它们 - 例如va_start.确切地说,这些宏所做的是实现定义 - 换句话说,它将从CPU架构到架构,从编译器到编译器.但是他们必须在C调用堆栈中玩弄技巧.通常,这将涉及将最后一个命名参数的地址作为基础,然后通过在此基础上执行指针算法来访问可变参数.