c-如何在变差函数上强制cdecl



我正在用g++编写一个64位操作系统,我有一个可变函数,比如:

void DbgPrint(const char *fmt, ...);

其行为将非常像printf。这里的问题是g++遵循System V ABI,因此它传递RDI、RSI、RDX、RCX、R8、R9中的第一个参数,然后推送堆栈上的剩余参数(如果有的话)。

将旧的stdarg.h宏va_start、va_arg等与cdecl一起使用非常容易,因为va_arg只是获取堆栈上的下一个元素。但现在这些宏要到第7个参数才能工作。

唯一可能的解决方案是(IMHO):

  • 强制g++创建一个cdecl函数。这似乎是不可能的,因为__属性__((cdecl))被故意清楚地突出显示为忽略
  • 拥有一组新的宏,这些宏使用新的传递参数的方式

(我实际上正在研究Win,所以我没有glibc头来检查它们的实现)。

有人有解决方案吗?提前谢谢。

stdarg.h不是libc的一部分,而是编译器本身的一部分。因此,如果你使用g++,它应该有一个stdarg.h来处理这个问题——它通常安装在gcc的私有include目录中,在系统include之前会自动搜索该目录。

如果你查看gcc的stdarg.h,你会发现va_宏都被定义为映射到__builtin函数,编译器神奇地知道如何处理这些函数:

typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;
#define va_start(v,l)   __builtin_va_start(v,l)
#define va_end(v)   __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)

并且这些内建都理解目标ABI所使用的调用约定。

最新更新