C++变长参数

如果C++的变长参数经过了多轮的调用,就可能失去作用

间接引址,但是只能引用到第一个变长参数。

va_list marker;
 
va_start(marker, format);
s_loggers[filename]->LoglineF(format, va_arg(marker, va_list));
va_end(marker);

或者,没有间接引址,就会造成地址的累积,从而没有引用到真正的参数,而是引用到上一次累积下来的marker地址。

va_list marker;
va_start(marker, format);
s_loggers[filename]->LoglineF(format, marker));
va_end(marker);

但是,其实不管怎样,只要让最后一步的marker指向参数列表,就不会出错。

marker是怎样取到的?

+        &format    0x01890e68    const char * *

#define va_start _crt_va_start
#define va_arg _crt_va_arg
#define va_end _crt_va_end

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap)      ( ap = (va_list)0 )

typedef char *  va_list;

但是当多了一层函数调用后,format的地址发生了变化

+        &format    0x01890e34    const char * *

因此va_start取到的marker就出现了错误。

怎么解?

时间: 2024-10-15 09:20:39

C++变长参数的相关文章

C++11 新特性之 变长参数模板

template <typename ... ARGS> void fun(ARGS ... args) 首先明确几个概念 1,模板参数包(template parameter pack):它指模板参数位置上的变长参数,例如上面例子中的ARGS 2,函数参数包(function parameter pack):它指函数参数位置上的变长参数,例如上面例子中的args 一般情况下 参数包必须在最后面,例如: template <typename T, typename ... Args>

Java语法糖初探(三)--变长参数

变长参数概念 在Java5 中提供了变长参数(varargs),也就是在方法定义中可以使用个数不确定的参数,对于同一方法可以使用不同个数的参数调用.形如 function(T -args).但是需要明确的一点是,java方法的变长参数只是语法糖,其本质上还是将变长的实际参数 varargs 包装为一个数组. 看下面的例子: 12345678910111213 public class VariVargs { public static void main(String []args) { tes

scala学习笔记-变长参数(5)

变长参数 在Scala中,有时我们需要将函数定义为参数个数可变的形式,则此时可以使用变长参数定义函数. 1 def sum(nums: Int*) = { 2 var res = 0 3 for (num <- nums) res += num 4 res 5 } 6 7 sum(1, 2, 3, 4, 5) 使用序列调用变长参数 在如果想要将一个已有的序列直接调用变长参数函数,是不对的.比如val s = sum(1 to 5).此时需要使用Scala特殊的语法将参数定义为序列,让Scala解

读书笔记:c语言标准库 - 变长参数

· 变长参数(stdarg.h) 变长参数是c语言的特殊参数形式,例如如下函数声明: int printf(const char * format,...); 如此的声明表明,printf函数除了第一个参数类型为const char*之外,其后可以追加任意数量.任意类型的参数. 在函数实现部分,可以使用stdarg.h里的多个宏来访问各个额外的参数:假设lastarg是变长参数函数的最后一个具名参数(printf里的format),那么在函数内容定义类型为va_list的变量: va_list

java 变长参数使用原则

1.java变长参数用...表示,如Print(String... args){  ... }; 2.如果一个调用既匹配一个固定参数方法,又匹配一个变长参数方法,则优先匹配固定参数的方法 3.如果一个调用能匹配两个及以上的变长参数方法,则出现错误--这其实表示方法设计有问题,编译器会提示The method is ambiguous 4.方法只能有一个变长参数,且必须放在参数列表的最后一个java 变长参数使用原则,布布扣,bubuko.com

java变长参数

从java5开始提供了变长参数,可以把变长参数当作数据使用 可变长参数方法的定义 使用...表示可变长参数,例如 print(String... args){ ... } 在具有可变长参数的方法中可以把参数当成数组使用,例如可以循环输出所有的参数值. print(String... args){ for(String temp:args) System.out.println(temp); } 可变长参数的方法的调用 调用的时候可以给出任意多个参数,例如: print("hello")

【Java】变长参数的坑

VarArgs VarArgs简述 只需要明确一点即可,java方法的变长参数只是语法糖,其本质上还是将变长的实际参数 varargs 包装为一个数组. 所以 Object[] objs 与 Object... objs 被看作是相同的签名,在源码级别是不能同时存在的,因此,无法编译通过 VarArgs包装 包装方式(注意,下面的代码不是实际的实现,而是一个比喻说明): 如果实参是唯一且匹配形参varargs要求的数组(就是实参独占形参varargs),那么可以认为你已经替编译器干了这个活,所以

scala学习手记21 - 传递变长参数

在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.println(tmp); } } 在scala中也可以使用变长参数.和java一样,也是只有最后一个参数可以接收可变长度的参数.使用方式是在参数类型后使用特殊符号"*",如下面的max()方法: def max(values: Int*) = values.foldLeft(values(0))

变长参数

先有如下需求:返回实参中的最大者.但由于实参的个数不确定,难以采用重载的办法. 解决:在定义方法时将形参的格式定义如下: int getMax(int first,int...varArgs){ for(int i:varAgus) .... } 调用: System.out.println("max(1)="+demo.getMax(1)+" ");//1 System.out.println("max(2)="+demo.getMax(2,1