如何在C中实现stdarg [英] How to implement stdarg in C
问题描述
出于好奇,我希望为标准C库中的某些功能编写最少的替代品.到目前为止,我已经完成了printf()
,strlen()
,strcpy()
,memcpy()
,memset()
等...,但是当我尝试使用printf函数时,我不知道如何实现
For curiosity, I'm looking to write minimal replacements for some of the functions in the standard C library. So far, I have finished printf()
, strlen()
, strcpy()
, memcpy()
, memset()
, etc... but when I try to use the printf function, I don't know how to implement stdarg.h
! What is a way that I could do that?
它使用宏还是实际函数?
Does it use macros or actual functions?
我正在32位x86上使用gcc
或clang
,如果这有助于使其更易于回答.
I am using gcc
OR clang
on 32-bit x86, if it helps to make this any easier to answer.
推荐答案
在具有cdecl调用约定的32位x86上,参数在堆栈上传递:
On 32-bit x86 with the cdecl calling convention, parameters are passed on the stack:
^ higher addresses (lower on the stack)
|
| caller local variables
| ...
| argument 3
| argument 2
| argument 1
| return address
| saved EBP (usually)
| callee local variables
|
v lower addresses (higher on the stack)
您可以将va_list
实现为指针. va_start
可以获取传递给它的参数的地址,并添加该参数的大小以移至下一个参数. va_arg
可以访问指针并将其碰到下一个参数. va_copy
可以只复制指针值. va_end
无需执行任何操作.
You can implement va_list
as a pointer. va_start
can take the address of the argument passed to it and add the size of that argument to move to the next argument. va_arg
can access the pointer and bump it to the next argument. va_copy
can just copy the pointer value. va_end
doesn’t need to do anything.
另一方面,如果您没有使用cdecl(也许正在使用fastcall),不是32位,不是x86,则此操作无效;您可能需要处理寄存器,而不仅仅是指针值.甚至仍然不能保证它能正常工作,因为您依赖的是不确定的行为;仅作为一个潜在问题的示例,内联会破坏所有内容.这就是为什么标头文件仅将其typedef
保存到内置的编译器中的原因-在C语言中实现该方法是没有希望的,您需要编译器支持.而且甚至不让我开始实施setjmp
和longjmp
…
If, on the other hand, you’re not using cdecl (maybe you’re using fastcall), you’re not 32-bit, you’re not x86, this won’t work; you might need to muck with registers rather than just pointer values. And even still it’s not guaranteed to work, since you’re relying on undefined behavior; as as example of only one potential problem, inlining could ruin everything. And that’s why the header file just typedef
s it to a compiler built-in—implementing this in C is hopeless, you need compiler support. And don’t even get me started on implementing setjmp
and longjmp
…
这篇关于如何在C中实现stdarg的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!