我写了一个使用va_list / va_arg / va_start / va_end / va_arg的printf myselef。
typedef char *va_list;
#define _AUPBND (sizeof (acpi_native_int) - 1)
#define _ADNBND (sizeof (acpi_native_int) - 1)
#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))
#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
#define va_end(ap) (void) 0
#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
首先,我从linux内核复制这些宏,printf可以打印32位整数正确,但不能打印64位整数,打印double / float可能会失败或崩溃。然后我检查代码,我猜va_ *可能有错误,所以我使用__builtin_va_ *而不是kernel的va _ *。
typedef __builtin_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)
但是gcc提示“未定义引用`abort'”,所以我写了一个空的abort()和myprintf正确地工作。 我的问题是:
va_list/va_arg/va_start/va_end/va_arg
不能用于printf
64位整数和双/浮?__builtin_va_start/__builtin_va_arg/__builtin_va_end/__builtin_va_list
时,为什么gcc会提示“未定义引用abort'"? But I can not find the definition of
__ builtin_va_ *`,这是他们的定义吗?答案 0 :(得分:3)
不要从Linux标题中剪切和粘贴内容。相反,将它放在源文件的顶部:
#include <stdarg.h>
这将为您提供使用va_list
和va_arg
所需的一切。但是,不会拉入printf
或任何标准I / O内容(位于<stdio.h>
中)。
答案 1 :(得分:1)
gcc的__builtin_va_arg()
显然会调用abort()
(至少在某些平台或情况下),如果使用类型参数调用它,则无法在参数列表的...
部分中传递一个函数调用。
例如,由于促销char
或float
已通过,因此此参数将被提升为int
或double
。以va_arg(ap,char)
或va_arg(ap,float)
访问这些参数是未定义的行为,gcc可能在这种情况下调用abort()
- 或者它可能会执行其他操作(我的MinGW编译器将执行无效指令以导致崩溃) )。
编译时可能会看到类似的内容:
In file included from D:\temp\test.c:2:0:
D:\temp\test.c: In function 'foo':
D:\temp\test.c:12:16: warning: 'char' is promoted to 'int' when passed through '...' [enabled by default]
c = va_arg(ap,char);
^
D:\temp\test.c:12:16: note: (so you should pass 'int' not 'char' to 'va_arg')
D:\temp\test.c:12:16: note: if this code is reached, the program will abort
__builtin_va_*
的'定义'被编译到编译器中(这就是为什么'builtin'是名称的一部分)。
对于varargs访问的Linux宏:虽然你从linux内核头文件中获取的定义确实存在于include / acpi / platform / acenv.h中,如果仔细查看有效的条件编译,你将会看看在构建linux内核时没有使用这些宏。我不确定这些宏何时生效,但它们不适用于x64 / x86-64 / amd64版本,因为该平台上的ABI不完全基于堆栈。有关详细信息,请参见“System V应用程序二进制接口 - AMD64架构处理器补充说明”的第3.5.6节。