stdarg.h#

stdargs.h提供了自定义的变参函数支持

Author

Shihong Wang (jack4shihong@gmail.com)

Version

0.2

Date

2023-04-09

Copyright

Copyright Shihong Wang (c) 2023 with GNU Public License V3.0

Note

deprecated, 原因见下. GCC调用时函数时通过栈传参, 因此参数在函数调用栈帧中依次排列. 所以变参宏的本质就是以字节的形式处理在栈中的依次排列的函数参数.

Note

参考: <path-to-riscv-gnu-toolchain-installation-path>/lib/gcc/riscv64-unknown-elf/12.2.0/include/stdarg.h

Warning

自己原先写的stdargs有BUG, 因为:

  1. x86-32 是全部通过栈传参

  2. RISC-V LP64的abi不是按照栈传参的, 先用寄存器再用栈, 所以如果要自己实现的话, 需要操作寄存器和栈 所以为了屏蔽不同的体系结构的ABI的差异, GCC使用了内建的__builtin_va_list, __builtin_va_start()__builtin_va_end() 因此如果需要自己实现RISV-Cstdargs.h的话, 就得参考GCC源码中的__builtin_va_list, __builtin_va_start()__builtin_va_end()RISC-V部分的实现 所以综合考虑, 还是直接需要使用GCC内建的 __builtin_va_list, __builtin_va_start()__builtin_va_end()算了

Warning

所有我自己写的stdargs.h适用于x86-32, 已经全部加上了_my_的前缀

Defines

va_start(ap, v)#

va_start用于将参数指针ap(argument pointer)指向第一个固定参数v

Note

使用GCC内建的__builtin_va_start作为将变参列表指向变参列表的的第一个参数

va_arg(ap, t)#

va_arg用于将参数指针ap(argument pointer)指向栈中下一个类型为t的参数.

Note

关于类型t, 需要注意的是:

  1. 默认传入的最小单位是int, 因此char的调用方式为: char varg_char = (unsigned char) va_arg(ap, int)

Note

使用GCC内建的__builtin_va_arg作为将变参列表指向下一个类型为t的参数

va_end(ap)#

_my_va_end用于清除参数指针ap(argument pointer)

Note

使用GCC内建的__builtin_va_end来清空变参列表

_my_va_start(ap, v)#

_my_va_start用于将参数指针ap(argument pointer)指向第一个固定参数v

弃用:

自己写的_my_va_list只适用于x86-32, 因此已经弃用, 详细的原因参考文件的doc

Parameters:
  • ap – 参数指针

  • v – 函数的第一个参数

_my_va_arg(ap, t)#

_my_va_arg用于将参数指针ap(argument pointer)指向栈中下一个类型为t的参数.

弃用:

自己写的_my_va_arg只适用于x86-32, 因此已经弃用, 详细的原因参考文件的doc

Note

由于是64位机器, 因此每次参数指针ap向后(高地址)增加8个字节

Parameters:
  • ap – 参数指针

  • t – 下一个参数的类型

_my_va_end(ap)#

_my_va_end用于清除参数指针ap(argument pointer)

弃用:

自己写的_my_va_end只适用于x86-32, 因此已经弃用, 详细的原因参考文件的doc

Parameters:
  • ap – 参数指针

Typedefs

typedef __builtin_va_list va_list#

变参列表类型, 本质就是一个指针, 因此也称为参数指针, 原理参考GCC编译器的传参原理

Note

使用GCC内建的__builtin_va_list作为变参列表类型

typedef char *_my_va_list#

变参宏以字节形式处理在栈中的函数参数, 因此变参列表_my_va_list的本质就是字节

弃用:

自己写的_my_va_list只适用于x86-32, 因此已经弃用, 详细的原因参考文件的doc