我见过的varargs.h和/或stdarg.h的所有版本要么将va_end定义为空宏,要么是一些不透明的特定于编译器的函数,我猜它们也不做任何事情。C标准中的基本原理指出“某些实现可能需要它”,但没有给出更多细节。什么时候会真实的需要va_end()?有任何ABI的例子需要这样做,最好有解释?
varargs.h
stdarg.h
va_end
va_end()
dffbzjpn1#
Fabrice Bellard的tcc的旧版本使用malloc()实现了va_start(),使用free()实现了va_end():因此,如果调用va_end()失败,将导致内存泄漏。这是因为它使va_list成为一个指向结构的指针,而malloc()/free()(或技术上的编译器内置)被用来分配/释放结构。在新版本的tcc中,va_list现在是一个结构的单元素数组,而不是一个指针,因此va_end()现在实际上是一个无操作,就像它通常一样。
tcc
malloc()
va_start()
free()
va_list
7vux5j2d2#
C语言已经存在了很长很长的时间,有很多标准。这些标准倾向于给予编译器一些回旋余地,让他们实现自己的填充/头/等。出于性能和其他原因。我认为这是因为,正如前面提到的,“一些编译器可能需要它。”尽管语言 * 尝试 * 抽象它们的实现细节,但有些东西-不可避免地-从裂缝中溜走了...希望对你有帮助=]
2条答案
按热度按时间dffbzjpn1#
Fabrice Bellard的
tcc
的旧版本使用malloc()
实现了va_start()
,使用free()
实现了va_end()
:因此,如果调用va_end()
失败,将导致内存泄漏。这是因为它使va_list
成为一个指向结构的指针,而malloc()
/free()
(或技术上的编译器内置)被用来分配/释放结构。在新版本的tcc
中,va_list
现在是一个结构的单元素数组,而不是一个指针,因此va_end()
现在实际上是一个无操作,就像它通常一样。7vux5j2d2#
C语言已经存在了很长很长的时间,有很多标准。这些标准倾向于给予编译器一些回旋余地,让他们实现自己的填充/头/等。出于性能和其他原因。我认为这是因为,正如前面提到的,“一些编译器可能需要它。”尽管语言 * 尝试 * 抽象它们的实现细节,但有些东西-不可避免地-从裂缝中溜走了...希望对你有帮助=]