博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【整理】关于 va_copy 的兼容性问题
阅读量:7034 次
发布时间:2019-06-28

本文共 2766 字,大约阅读时间需要 9 分钟。

hot3.png

首先查看 Linux 下的 man 信息。
[root@Betty ~]# man va_copySTDARG(3)                  Linux Programmer’s Manual                 STDARG(3)NAME       stdarg - variable argument listsSYNOPSIS       #include 
void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src); ... ... va_copy An obvious implementation would have a va_list be a pointer to the stack frame of the variadic function. In such a setup (by far the most common) there seems nothing against an assignment 一种最常见的实现是将 va_list 作为指向变参函数栈帧的指针使用。在这种情况下(最常见情况),va_copy 的功能和下面的赋值操作可以等价 va_list aq = ap; Unfortunately, there are also systems that make it an array of pointers (of length 1), and there one needs 不幸的是,有一些系统将 va_list 实现成了指针数组(长度为 1),故操作必须如下才能保证正确 va_list aq; *aq = *ap; Finally, on systems where parameters are passed in registers, it may be necessary for va_start() to allocate memory, store the parameters there, and also an indication of which parameter is next, so that va_arg() can step through the list. Now va_end() can free the allocated memory again. To accommodate this situation, C99 adds a macro va_copy(), so that the above assignment can be replaced by 在使用寄存器(register)传参的系统上,va_start() 函数会负责所需内存的分配以及相应参数值的存储,并且会指示下一个待处理的参数是 谁,以便于 va_arg() 能够遍历变参列表。va_end() 会负责分配内存的释放工作。为了满足上述行为,C99 添加了宏定义 va_copy(),所以 上面的赋值操作可以被下面的代码替代 va_list aq; va_copy(aq, ap); ... va_end(aq); Each invocation of va_copy() must be matched by a corresponding invocation of va_end() in the same function. Some systems that do not supply va_copy() have __va_copy instead, since that was the name used in the draft proposal. 每一次对 va_copy() 的调用都必须与 va_end() 进行配对(同一个函数内部)。一些系统上不支持 va_copy() 但是提供了 __va_copy() 也 是可以的,该名字的由来是因为在草案中就是这个。CONFORMING TO The va_start(), va_arg(), and va_end() macros conform to C89. C99 defines the va_copy() macro. va_copy() 是在 C99 中被支持的。

       有了上述信息,就可以大体确认了 VS2010 是不支持 va_copy() 的,同时发现其对 __va_copy() 也不支持。所以,只能自己实现一个替代方案了。

在 MySQL 5.6.10 中有如下的兼容性代码:
#ifndef va_copy#define	va_copy(dst, src)	memcpy(&(dst), &(src), sizeof(va_list))#endifva_copy(aq, ap);

在 Jansson-2.5 库中的 jansson_private.h 中有如下定义

/* va_copy is a C99 feature. In C89 implementations, it's sometimes   available as __va_copy. If not, memcpy() should do the trick. */#ifndef va_copy#ifdef __va_copy#define va_copy __va_copy#else#define va_copy(a, b)  memcpy(&(a), &(b), sizeof(va_list))#endif#endif
      
另外在 stackoverflow 上有关于这个问题的讨论:

转载于:https://my.oschina.net/moooofly/blog/185606

你可能感兴趣的文章
.NET开发规范教程
查看>>
网络公开课《最后的升级-Oracle RAC数据库升级》
查看>>
配置FTP服务
查看>>
我的友情链接
查看>>
人类认识的层次模型
查看>>
WDS使用捕获映像制作企业自定义映像
查看>>
C++数组、指针与vector、iterator
查看>>
SSL及其开源实现OpenSSL+创建私有CA
查看>>
jquery实现表单form异步提交
查看>>
Citrix xendesktop中未注册(Not registered)的检查流程
查看>>
一张图让你看懂JAVA线程间的状态转换
查看>>
Performance comparison Raw device VS Ext2 VS Ext3 VS OCFS
查看>>
ISBN号码(CCF考题)
查看>>
PendingIntent中Flags的参数设置
查看>>
企业级镜像仓库harbor搭建(http/https)及使用
查看>>
从MySQL到MongoDB简易对照表 (转)
查看>>
python爬取某个网页的图片-如百度贴吧
查看>>
使用httpwatch抓包
查看>>
新建主机及虚拟机
查看>>
dbverify的时候报错 DBV-00600: Fatal Error – [21] [2] [0] [0]
查看>>