背景:我目前正在尝试通过支持处理某些结构来“扩展”标准C格式,类似于Objective-C如何扩展C格式以允许对带有“%@”序列的NSString的支持。
我苦苦挣扎的一个问题是vsprintf在OS X和Linux上的行为似乎有所不同(我已经在Ubuntu 10.10和12.04上进行了测试)。在OS X上,它表现的是我的预期,在调用vsprintf之后,调用va_arg返回ms指针(就像vsprintf函数调用va_arg来获得5一样)。但是,在Linux上,va_list不会从vsprintf更改,并且调用va_arg返回5。
我真的很想找出一种实现此功能的方法,以使其在各个平台之间始终如一地运行。假设您可以期望vsprintf持续更改va_list中的指针是错误的,以便下次调用va_arg时,它返回下一个尚未使用的参数?
我已尽可能简化了代码以演示该问题。在OS X上,此代码输出从malloc返回的指针的正确地址。在Linux上,foo中的ms的值变为5,因此它将输出5。
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
static void foo(void *, ...);
typedef struct {
char *value;
} mystruct;
int main(int argc, char *argv[]) {
mystruct *ms = malloc(sizeof(mystruct));
foo(NULL, "%d %@", 5, ms);
}
void foo(void *dummy, ...) {
va_list args;
va_start(args, dummy);
char buffer[512];
int buffer_ptr = 0;
int i = 0;
char *format = va_arg(args, char *);
buffer[0] = '\0';
for (i = 0; i < strlen(format); i++) …Run Code Online (Sandbox Code Playgroud)