当前位置:  开发笔记 > 编程语言 > 正文

va_end究竟是什么?是否总是需要打电话给它?

如何解决《va_end究竟是什么?是否总是需要打电话给它?》经验,为你挑选了3个好方法。

va_end用于清理.你不想粉碎堆栈,对吗?

来自man va_start:

va_end用来()

每次调用va_start()都必须与同一函数中相应的va_end()调用相匹配.在调用va_end(ap)之后,变量ap未定义.列表的多次遍历,每个遍历由va_start()和va_end()括起来都是可能的.va_end()可以是宏或函数.

注意必须存在单词.

堆栈可能会损坏,因为您不知道va_start()正在做什么.这些va_*宏意味着被视为黑盒子.每个平台上的每个编译器都可以做任何想做的事情.它可能什么都不做,或者可能做很多事情.

一些ABI将最初的几个args传递给寄存器,其余的则传递给堆栈.一个va_arg()有可能更为复杂.您可以查看给定实现如何执行varargs,这可能很有趣,但在编写可移植代码时,您应该将它们视为不透明操作.



1> greyfade..:

va_end用于清理.你不想粉碎堆栈,对吗?

来自man va_start:

va_end用来()

每次调用va_start()都必须与同一函数中相应的va_end()调用相匹配.在调用va_end(ap)之后,变量ap未定义.列表的多次遍历,每个遍历由va_start()和va_end()括起来都是可能的.va_end()可以是宏或函数.

注意必须存在单词.

堆栈可能会损坏,因为您不知道va_start()正在做什么.这些va_*宏意味着被视为黑盒子.每个平台上的每个编译器都可以做任何想做的事情.它可能什么都不做,或者可能做很多事情.

一些ABI将最初的几个args传递给寄存器,其余的则传递给堆栈.一个va_arg()有可能更为复杂.您可以查看给定实现如何执行varargs,这可能很有趣,但在编写可移植代码时,您应该将它们视为不透明操作.


C语言原理提到某些实现在`va_start`中分配内存.因此,'va_end`将释放内存."在许多实现中,[`va_end`]是一个无操作的操作;但那些需要它的实现可能需要它."
没有人真正解释va_end()实现的细节,我认为,问题是什么.
@Adam:显然取决于平台.对于许多机器来说,这是一个无操作.这意味着您可以忽略关于必须使用va_end()的标准限制,并且您将大部分使用它 - 但它是非常愚蠢的编码.非常愚蠢!
确实.一些ABI在寄存器中传递了几个args,并保留在堆栈中.一个va_arg可能会更复杂.有些很容易......你永远不会知道
它可能会被破坏,因为*你不知道va_start()正在做什么.*它可能正在做任何事情.它需要清理.因此,当你调用va_start()时,你*必须*与va_end()匹配.
va_*宏意味着被视为黑盒子.每个平台上的每个编译器都可以做任何想做的事情.它可能什么都不做,或者可能做很多事情.你不知道.这是我的观点.

2> Maxim Egorus..:

在Linux x86-64上,只能对va_list变量进行一次遍历.要进行更多遍历,必须先使用它进行复制va_copy.man va_copy解释细节:

va_copy()

一个明显的实现将使va_list成为指向可变参数函数的堆栈帧的指针.在这样的设置中(到目前为止最常见),似乎没有任何反对任务

   va_list aq = ap;

不幸的是,还有一些系统使它成为一个指针数组(长度为1),并且需要它

   va_list aq;
   *aq = *ap;

最后,在寄存器中传递参数的系统上,va_start()可能需要分配内存,在那里存储参数,以及下一个参数的指示,以便va_arg()可以遍历列表.现在,va_end()可以再次释放分配的内存.为了适应这种情况,C99添加了一个宏va_copy(),以便上面的赋值可以替换为

   va_list aq;
   va_copy(aq, ap);
   ...
   va_end(aq);

每次调用va_copy()都必须与同一函数中相应的va_end()调用相匹配.某些不提供va_copy()的系统会改为使用__va_copy,因为这是提案草案中使用的名称.


要克服这个; Linux x86-64没什么特别之处.当你只有`va_list`变量可用时,如果你想在列表上迭代两次,则需要`va_copy`.(例如在以'va_list`作为参数的函数内部).您可以随时调用`va_start`和`va_end`.

3> James Curran..:

在常见的"在堆栈上传递的参数"实现中,我相信va_end()通常没有/ empty/null.但是,在传统方案较少的平台上,这是必要的.包含它以保持平台中立是一种"好习惯".

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有