文档章节

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

摩云飞
 摩云飞
发布于 2013/12/18 15:43
字数 674
阅读 90
收藏 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 上有关于这个问题的讨论:这里

© 著作权归作者所有

共有 人打赏支持
摩云飞
粉丝 368
博文 534
码字总数 952694
作品 0
徐汇
程序员
C语言深入浅出可变参数函数的使用技巧

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

Start-up
2012/10/19
0
0
Effective C++: 省略符形参

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

SHIHUAMarryMe
2016/11/23
35
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
0
深入浅出VA函数

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

XDATAPLUS
2016/06/13
0
0
函数可变参数

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

晨曦之光
2012/04/13
67
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Memcached启动参数详解

memcached -d -m 1024 -l 192.168.100.101 -p 11211 -P /tmp/memcached.pid -c 1024 -f 1.25 -n 80 -t 16 运行参数描述 -d:以守护(daemon)进程方式启动; -u:是运行Memcache的用户,例如 ......

月下狼
32分钟前
0
0
xgboost-kaggle

https://www.kaggle.com/dansbecker/xgboost This tutorial is part of the Learn Machine Learning series. In this step, you will learn how to build and optimize models with the powe......

tantexian
33分钟前
0
0
nginx学习八 代理服务

最常用的语法 proxy_pass Syntax: proxy_pass URL;Default: --Context:location.if in location,limit_exception 反向代理 例:/etc/nginx/conf.d/default.conf 反向代理(代理服务端)......

Romanceling
40分钟前
0
0
npm ERR! Unexpected end of JSON ...

npm install 报错: npm ERR! Unexpected end of JSON input while parsing near '..."^2.8.14"},"_hasShrin' npm ERR! A complete log of this run can be found in: ... 打开终端 命令: 第......

大_侠
44分钟前
0
0
Android中的设计模式之责任链模式

参考 《设计模式:可复用面向对象软件的基础 》5.1 Chain of responsibility 职责链 对象行为型模式 《Android源码设计模式解析与实战》第9章 使编程更有灵活性--责任链模式 意图 使多个对象...

newtrek
47分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部