gpt4 book ai didi

c++ - 抛出异常时是否需要 va_end?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:28:23 26 4
gpt4 key购买 nike

我有一个基于 printf 样式格式的日志记录框架:

void Logger::debug(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
this->output(DebugLevel, fmt, args);
va_end(args);
}

如果 Logger::output 抛出异常,编译器是否会正确展开堆栈,或者我是否需要在捕获条款?这可以改为 RAII,还是 va_end 太神奇了?如果可能,请包括对标准的引用。

最佳答案

不,他们不能。因为它们是宏而不能的推理是愚蠢的。宏可以毫无问题地从构造函数和析构函数中使用。然而,va_startva_end有特定要求,必须从同一函数调用它们。将它们移动到单独的函数是无效的。 C++ 指的是 C 标准,C 标准表示“每次调用 va_startva_copy 宏都应与同一函数中相应的 va_end 宏调用相匹配。” (7.15.1) 如果你调用va_end从辅助类的析构函数,它可能有效,也可能无效。由于不符合标准要求,因此行为未定义。

编辑:至于另一个问题,你需要va_end吗?在抛出异常时,可以提出一个合理的论点,即“调用 va_end 宏”实际上并不要求代码到达调用该宏的位置(因为宏调用严格来说是编译时-only action),但它强烈表明你确实需要它。所以是的,使用 try/catch如果有可能出现异常(exception)情况。 C99 基本原理在其对 va_copy 的描述中简要说明那va_start可以分配内存。 (我知道没有实际这样做的实现。)在这样的实现中,va_end然后将释放该内存,因此跳过 va_end会导致内存泄漏。

关于c++ - 抛出异常时是否需要 va_end?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11645282/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com