Hos*_*ork 11 c variadic-functions c89 language-lawyer longjmp
在此问答中,您应该始终致电va_end():
但是如果你到达va_end之前有一段代码longjmp呢?va_end的部分是否有任何承诺可以接受?或者从概念上讲(例如)va_start()可能会泄漏内存分配,而不仅仅是使用堆栈技巧?
小智 8
该C99理由明确规定,va_start可分配内存最终被释放va_end,你在你的问题猜到了什么:
7.15.1.2
va_copy宏[...]
30一种更简单的方法是复制
va_list用于表示参数处理的对象.但是,在C89中没有安全的方法可以执行此操作,因为该对象可能包含指向由va_start宏分配并由宏销毁的内存的指针va_end.
新va_copy宏提供了这种安全机制.[...]
所以是的,你需要va_end在a之前调用longjmp.至少你会在这样的实现上发生内存泄漏.
据说金字塔OSx有一个实现内存分配的实现va_start.函数参数在寄存器中传递.即使对于可变函数也是如此.它可能早于ANSI C发明的函数原型,这意味着调用者不知道它是否处理可变函数.va_start分配内存,大概是以一种va_arg可以轻松访问它的方式存储函数参数值.va_end释放分配的内存.
它的实现va_start和va_end实际需要匹配va_start和va_end语法,因为它是一个使用不平衡的括号,所以ANSI C已经不允许该实现,但同样的原则可以在匹配括号时工作.
我可以找到关于这个实现的非常少的具体信息,它在80年代末,90年代早期的Usenet上只是点点滴滴.我找到的一点点可能是不完整的,甚至是完全错误的.更多细节非常受欢迎,尤其是那些自己使用此实现的人.