文档章节

【整理】关于 va_copy 的兼容性问题

摩云飞
 摩云飞
发布于 2013/12/18 15:43
字数 674
阅读 88
收藏 0
点赞 0
评论 0

首先查看 Linux 下的 man 信息。
[root@Betty ~]# man va_copy
STDARG(3)                  Linux Programmer’s Manual                 STDARG(3)

NAME
       stdarg - variable argument lists

SYNOPSIS
       #include <stdarg.h>

       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))
#endif
va_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 上有关于这个问题的讨论:这里

© 著作权归作者所有

共有 人打赏支持
摩云飞
粉丝 364
博文 352
码字总数 952690
作品 0
徐汇
程序员
C/C++ 实现可变参数

引言 C语言支持可变参数,即参数个数不固定,典型的函数如printf, scanf等可以接受数量不定的参数。 如,printf("one parameter");printf("two parameter: %d", a);printf("three parameter:...

恋恋美食 ⋅ 2013/03/11 ⋅ 0

C语言深入浅出可变参数函数的使用技巧

C语言深入浅出可变参数函数的使用技巧(转) 深入浅出可变参数函数的使用技巧本文主要介绍可变参数的函数使用,然后分析它的原理,程序员自己如何对它们实 现和封装,最后是可能会出现的问题...

Start-up ⋅ 2012/10/19 ⋅ 0

Effective C++: 省略符形参

Notice: 省略符形参并不是可变模板参数! 同时这是针对非模板的可变参数解决方案!!!!!!! 再C中有一个函数: int printf(const char* format, ...); 这里的 "..."一直不明白是什么意思,...

SHIHUAMarryMe ⋅ 2016/11/23 ⋅ 0

可变参数: va_start,va_arg,va_end

vastart,vaarg,va_end是在stdarg.h中被定义成宏的, 由于1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下 面以VC++中stdarg.h里x86平台的宏定义摘录如下(’’号表示折行): typede...

Start-up ⋅ 2012/05/08 ⋅ 0

深入浅出VA函数

VA函数(variable argument function),参数个数可变函数,又称可变参数函数。C/C++编程中,系统提供给编程人员的va函数很少。printf()/scanf()系列函数,用于输入输出时格式化字符串;exe...

XDATAPLUS ⋅ 2016/06/13 ⋅ 0

函数可变参数

#include include using namespace std; // 求若干数的平方和//第一个参数是参数的个数double pingfangsum(int a,...){double sum = 0,num;valist vararg; //定义一个指向个数可变的参数列表...

晨曦之光 ⋅ 2012/04/13 ⋅ 0

C 不定长参数

C语言可变参简介 我们在C语言编程中会遇到一些参数个数可变的函数,例如printf()这个函数,它的定义是这样的:    int printf( const char* format, ...);   它除了有一个参数format固定以外...

MrLovelyCbb ⋅ 2016/09/05 ⋅ 0

Obj-C打印数组的问题

请问,关于一个Object-c的数组的问题!!!!!!! [self abc:@"1",@"2",@"3"]; (void)abc:(NSString*)str, ...{ NSLog(@"%@,%@,%@",str,?,?); } 请问怎么在abc中把1、2、3打印出来? (voi...

Lambda8421 ⋅ 2015/02/28 ⋅ 0

va_start va_arg va_end 的原理与实例

func( Type para1, Type para2, Type para3, ... ) { / Step 1 / valist ap; vastart( ap, para3 ); //一定要“...”之前的那个参数ap指向para后的第一个可变参数。 / Step 2 / //此时ap指向......

长平狐 ⋅ 2013/01/06 ⋅ 0

mobile web 前端研发流程 【转载】

接触Mobile WEB前端开发将近一年时间了,在这不算短的时间里,通过吸取圆心、沉鱼等前辈们的经验以及不断的摸索和实战,总结出一套自己的Mobile WEB“研发流程”。为什么叫“研发”流程而不是...

石秋风 ⋅ 2012/04/18 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

vim编辑模式、vim命令模式、vim实践

vim编辑模式 编辑模式用来输入或修改文本内容,编辑模式除了Esc外其他键几乎都是输入 如何进入编辑模式 一般模式输入以下按键,均可进入编辑模式,左下角提示 insert(中文为插入) 字样 i ...

蛋黄Yolks ⋅ 昨天 ⋅ 0

大数据入门基础:SSH介绍

什么是ssh 简单说,SSH是一种网络协议,用于计算机之间的加密登录。 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码...

董黎明 ⋅ 昨天 ⋅ 0

web3j教程

web3j是一个轻量级、高度模块化、响应式、类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。 汇智网最新发布的web3j教程,详细讲解...

汇智网教程 ⋅ 昨天 ⋅ 0

谷歌:安全问题机制并不如你想象中安全

腾讯科技讯 5月25日,如今的你或许已经对许多网站所使用的“安全问题机制”习以为常了,但你真的认为包括“你第一个宠物的名字是什么?”这些问题能够保障你的帐户安全吗? 根据谷歌(微博)安...

问题终结者 ⋅ 昨天 ⋅ 0

聊聊spring cloud gateway的RedisRateLimiter

序 本文主要研究下spring cloud gateway的RedisRateLimiter GatewayRedisAutoConfiguration spring-cloud-gateway-core-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/gateway/con......

go4it ⋅ 昨天 ⋅ 0

169. Majority Element - LeetCode

Question 169. Majority Element Solution 思路:构造一个map存储每个数字出现的次数,然后遍历map返回出现次数大于数组一半的数字. 还有一种思路是:对这个数组排序,次数超过n/2的元素必然在中...

yysue ⋅ 昨天 ⋅ 0

NFS

14.1 NFS介绍 NFS是Network File System的缩写 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netapp公司参与并主导开发,最新为4.1版本 NFS数据传输基于RPC协议,RPC...

派派菠菜 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部