基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同;在使用中需要注意的是:

  va_list 为char 类型指针,部分调用如vnsprintf、vsprintf(内部通过遍历获取va_arg各个参数值)等会修改其指针位置;在windows下通过一个副本va_list实现va_arg操作,而在linux下不会产生副本va_list,而是直接修改原va_list的指针对象;

  在编写程序的时候,当调用了类似vnsprintf的函数后,若再次调用vnsprintf相关的其他需要用到va_list定义的类型指针对象时,将可能出现非预期的结果;在linux下便是如此,故当调用了类似vnsprintf的函数后应再次调用va_start,以重新调整va_list对象的指针位置(windows下无需再调用)。

示例代码段:

  

std::string formatstr(const char *format, ...)
{
std::vector<char> vec_str;
va_list arg_list;
va_start(arg_list, format);
int len = vsnprintf(nullptr, 0, format, arg_list);
if( len > 0 )
{
vec_str.resize( len + 1);
//va_start(arg_list, format);
vsnprintf(&vec_str[0], len, format, arg_list);
}
va_end(arg_list);
if(vec_str.size() > 0)
{
vec_str[len] = '\0';
return &vec_str[0];
} return std::string("");
}

  在windows的vs平台下以上代码可为预期结果,而在linux下输出却是随机的;若将注释段代码打开,则均可输出预期的结果;

  

C语言的可变参数在Linux(Ubuntu)与Windows下注意点的更多相关文章

  1. C语言中可变参数的函数(三个点,“...”)

    C语言中可变参数的函数(三个点,“...”) 本文主要介绍va_start和va_end的使用及原理. 在以前的一篇帖子Format MessageBox 详解中曾使用到va_start和va_end ...

  2. [11 Go语言基础-可变参数函数]

    [11 Go语言基础-可变参数函数] 可变参数函数 什么是可变参数函数 可变参数函数是一种参数个数可变的函数. 语法 如果函数最后一个参数被记作 ...T ,这时函数可以接受任意个 T 类型参数作为最 ...

  3. Linux程序在Windows下编译运行_MinGW和Cygwin

    linux要在windows下编译运行,需要win下的gcc编译器,一般有两种:MinGW和Cygwin. 但某些函数在windows没有,即使使用两种工具也编译不过,需要查询windows函数并使用 ...

  4. C语言中可变参数的用法

    原文地址: http://blog.csdn.net/wooin/archive/2006/04/29/697106.aspx   我们在C语言编程中会遇到一些参数个数可变的函数,例如printf() ...

  5. C语言中可变参数函数实现原理

    C函数调用的栈结构 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈.例如,对于函数: void fu ...

  6. C语言函数可变参数列表

    C语言允许使用可变参数列表,我们常用的printf函数即为可变参数函数,C标准库提供了stdarg.h为我们提供了这方面支持:该头文件提供了一些类型和宏来支持可变参数列表,包括类型va_list,宏v ...

  7. C语言中可变参数的使用

    在C语言程序编写中我们使用最多的函数一定包括printf以及很多类似的变形体.这个函数包含在C库函数中,定义为 int printf( const char* format, ...); 除了一个格式 ...

  8. C语言中可变参数的原理——printf()函数

    函数原型: int printf(const char *format[,argument]...) 返 回 值: 成功则返回实际输出的字符数,失败返回-1. 函数说明: 使用过C语言的人所再熟悉不过 ...

  9. C语言的可变参数

    可变参数给编程带来了很大的方便,在享受它带来的方便的同时,很有必要了解一下其实现方式,在了解编程语言的同时,也可以扩展编程的思路. 可变参数需要用到3个宏函数和一个类型,他们都定义在<stdar ...

随机推荐

  1. 几种常见的Shell

    Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把它们称作一种Shell.我们常说有多少种Shell,其实说的是Shell脚本解释器. bash bash是L ...

  2. 纯CSS3实现动态导航栏目

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. jdk自带的jvm监测程序

    jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号. jstat:一个极强 ...

  4. python 反射

    python 反射的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动! 反射的四个基本函数使用 hasattr,getattr,setatt ...

  5. 使用powershell批量添加Qt的文件(生成pro)

    想使用QtCreator作为编辑器编辑keil或者IAR的工程,需要生成.pro文件,于是使用powershell批量处理. 源码如下: $incPath = dir -filter "*. ...

  6. Mysql中sql_mode详解

    阅读目录 简介 sql_mode常用值 session与global 简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进 ...

  7. leetcode笔记

    82. Remove Duplicates from Sorted List II https://leetcode.com/problems/remove-duplicates-from-sorte ...

  8. struts.xml

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC    " ...

  9. linux glances的基本使用

    一.Glances介绍 glances 是一款用于 Linux.BSD 的开源命令行系统监视工具,它使用 Python 语言开发,能够监视 CPU.负载.内存.磁盘 I/O.网络流量.文件系统.系统温 ...

  10. D3.js学习(五)

    上一节我们已经学习了如何设置填充区域,其实理解了他的实现原理还是非常简单了.这一节中, 我们主要学习多条曲线的绘制,以及给不同的曲线指定不同的纵坐标. 新的数据 由于我们要画两条曲线,所以我们要在原来 ...