gpt4 book ai didi

c++ - 多个 va_end 调用的顺序是否重要?

转载 作者:可可西里 更新时间:2023-11-01 18:32:12 25 4
gpt4 key购买 nike

我有以下代码:

va_list va[2];
va_start(va[0], fmt);
va_start(va[1], fmt);
process(fmt, va);
va_end(va[0]);
va_end(va[1]);

我查看了各种站点以获取关于 va_startva_end 的文档,他们只说 va_end 应该为每个调用va_start 在调用函数返回之前。

我不确定调用顺序是否重要。特别是,是

va_end(va[0]);
va_end(va[1]);

在语义上与

相同
va_end(va[1]);
va_end(va[0]);

在上面的示例代码中?

最佳答案

C99 标准中唯一相关的要求是:

7.15.1 Variable argument list access macros

1 [...] Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function.

多个va_end的顺序没有要求与 va_start 匹配的调用, 或与 va_start 的反向匹配,因此实现需要接受任一顺序。

你甚至可以使用像这样一团糟

void f(int a, ...) {
va_list ap;
goto b;
a:
va_end(ap);
return;
b:
va_start(ap, a);
goto a;
}

这符合标准的所有要求,因此实现必须接受它。结果,即使是va_end不允许扩展为带有不匹配大括号的内容。

在实践中,我什至不知道任何当前的实现 va_end有任何必要的效果。我能够找到的所有实现最多将值(或第一个子值,取决于类型)设置为零,这将进一步使用 va_arg失败,但如果省略 va_end 也不会导致问题从你的代码。大多数人甚至不这样做。现在,我实际上不会从代码中删除它,因为有合理的理由说明一个实现(当前或 future )实际上可能在其 va_end 中做某事。 ,但您可以假设当前和 future 的实现至少会尝试以符合标准要求的方式实现它。

使用 #define va_end(ap) } 的历史实现就是这样:历史。他们没有在 <stdarg.h> 中提供该宏,他们甚至没有 <stdarg.h> header 。你不应该担心他们。

关于c++ - 多个 va_end 调用的顺序是否重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25652021/

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