c ++ va_arg类型转换问题

时间:2010-12-29 20:28:14

标签: c++ variadic-functions

所有

我正在编写一个小型的c ++应用程序并且被这个问题困扰了。如果不期望元素类型,有没有办法在使用va_arg从va_list宏访问元素时创建(以及稍后捕获)错误。例如: -

count=va_arg(argp,int); 
if (count <= 0 || count > 30)
{   
      reportParamError();   return;
}

现在,如果我传递的是typedef而不是int,我会在MS编译器上获得垃圾值,但95%的时间计数在gcc上获得值0(在64位sles10 sys上)。有没有办法可以强制执行一些类型检查,以便我得到一个可以在catch块中捕获的错误?

任何关于此的想法对我都非常有帮助。或者有更好的方法来做到这一点。函数原型是: -

 void process(App_Context * pActx, ...) 

该函数被称为

 process(pAtctx,3,type1,type2,type3);

pActx必须作为第一个参数传递,因此不能将计数作为第一个参数传递。


更新-1

好的,这听起来很奇怪,但是在sles10 gcc上,nargs似乎不属于va_list。我不得不放入

#ifdef _WIN32
tempCount=va_arg(argp,int)
#endif

使用此功能后,nargs之后的参数不会获得垃圾值。但是,这引入了基于编译器/平台的#ifdefs ....感谢Chris和Kristopher

2 个答案:

答案 0 :(得分:5)

如果您知道计数将始终作为第二个参数传递,那么您可以随时将签名更改为:

void process(App_Context * pActx, int count, ...) 

如果这不是一个选项,那么真的没办法抓住它。这就是变量参数列表的工作原理:除了调用者传递的任何信息之外,被调用者无法知道传递的参数是什么。

如果你研究如何实现va_arg宏和相关的宏,你可能能够弄清楚如何检查堆栈上的所有东西。但是,这不是便携式的,除了作为调试辅助工具外,不建议这样做。

您可能还想查看变量参数的替代方法,例如函数重载,模板或传递vectorlist个参数。

答案 1 :(得分:2)

不,没有办法。 varargs没有提供任何方法来检查传入的参数类型。您只能使用正确的类型读取它们,这意味着您需要另一种方式来传递类型信息。

除非你真的需要,否则你可能会更好地避免使用varargs功能。它只是为了printf和朋友等遗留功能而真正的C ++功能。