c – 如何在GCC上创建va_list?

c – 如何在GCC上创建va_list?,第1张

概述我正在尝试转换一些代码,以便它也在 gcc上编译(现在,它仅在MSVC上编译). 我坚持的代码是伪格式化函数,它接受一个格式字符串和零个或多个参数(const char * format,…)作为输入.然后它将处理一些占用一些参数的占位符,并将其余的传递给vsprintf以及动态生成的新va_list. 这是生成新va_list的实际代码: char *new_args = (char *) ma 我正在尝试转换一些代码,以便它也在 gcc上编译(现在,它仅在MSVC上编译).

我坚持的代码是伪格式化函数,它接受一个格式字符串和零个或多个参数(const char * format,…)作为输入.然后它将处理一些占用一些参数的占位符,并将其余的传递给vsprintf以及动态生成的新va_List.

这是生成新va_List的实际代码:

char *new_args = (char *) malloc(sum);char *n = new_args;for(int i = 0; i < nArgs; i++){    int j   = order[i];    int len = _getlen(types[j]);    memcpy(n,args + cumulOffsets[j],len);    n += len;}vsprintf(buffer,sFormat.c_str(),new_args);

在我的辩护中,我没有,也绝不会写这段代码.事实上,我认为这是我一生中见过的最讨厌的事情之一.

但是,这个功能非常复杂,非常陈旧,非常重要.它也没有被修改多年(好吧,除了现在),所以虽然我想从头开始重写它,但我无法证明它需要的时间加上它会引入的错误.

所以,我需要一种方法在GCC上做同样的事情..但是有一个va_List不是char *所以我得到:

error: ISO C++ forbIDs casting to an array type '__va_List_tag [1]'
解决方法 我有点迷茫.为什么需要一个新的动态生成的va_List?为什么不重用旧的呢?

我相信vsnprintf()使用当前的va_List对象(如果你可以调用它).所以你可以自由地使用va_start(),通过va_arg()使用你想要的参数,然后通过va_List将剩下的参数传递给vsnprintf(),然后调用va_end().

我错过了什么吗?为什么深拷贝?

如果你确实需要深层复制,为什么不刷新va_start(),通过va_arg()删除你想要的参数,然后将生成的va_List对象传递给vsnprintf().

(每次调用va_arg都会修改va_List对象,以便下一个调用返回下一个参数.)

或者,您可以使用va_copy(). (尽管一定要用相应的va_end()跟随它.)

附录:另请注意,这些va_宏基于C89& C99标准. GNU g将支持它们.微软有点受限.

跟进TonyK的评论:

如果您从va_List中删除前N个项目,我上面所说的就可以了.如果你从中间拉出物品,那就更难了.

没有可移植的方法来构造va_List.

但是,您可以拆分格式字符串,使用它来确定对象类型(double,float,int等),并使用它自己的格式字符串(原始格式字符串的子部分)单独打印每个字符串.多个snprintf()调用将导致一些开销.但如果不经常调用这个例程,它应该是可行的.

您还可以使用适当制作的va_List打印出原始格式字符串的子部分.换句话说,第一个vsnprintf()调用打印元素1..3,第二个元素5..7,第三个10..13等等(因为vsnprintf()会忽略va_List上的额外元素超出它的需要你只需要一系列相应的格式字符串片段,并根据每个vsnprintf()调用的需要用va_arg()d出va_List中的项目.)

总结

以上是内存溢出为你收集整理的c – 如何在GCC上创建va_list?全部内容,希望文章能够帮你解决c – 如何在GCC上创建va_list?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1241476.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存