gpt4 book ai didi

c - C 中的可变参数函数

转载 作者:太空宇宙 更新时间:2023-11-04 01:32:45 25 4
gpt4 key购买 nike

我有一个函数看起来像

void demo_function_v(const char * mask, va_list ap)
{
for (; *mask; mask++) {
// get one or more args from ap, depending on *mask
}
}

这在 AVR 系统上运行,该系统对闪存具有不同的访问技术。为了复制这个函数,我想提取它的主要部分:

void demo_function_1char(char mask, va_list ap)
{
// get one or more args from ap, depending on mask
}

void demo_function_v(const char * mask, va_list ap)
{
for (; *mask; mask++) {
demo_function_1char(*mask, ap)
}
}

唉,这不能保证有效,因为

The object ap may be passed as an argument to another function; if that function invokes the va_arg macro with parameter ap, the value of ap in the calling function is indeterminate.

这是真的 - 在 x86 上,它不起作用,在 x64 上,它可以。如果它适用于 AVR,我明天就可以测试。但如果它被描述为“不确定”(据说是一种 UB),我宁愿不依赖它。

因此,我想走另一条路:

void demo_function_1char(char mask, va_list * pap)
{
// get one or more args from *pap, depending on mask
}

void demo_function_v(const char * mask, va_list ap)
{
for (; *mask; mask++) {
demo_function_1char(*mask, &ap)
}
}

这应该行得通吗,或者我也会这样射脚吗?

最佳答案

C99 标准有以下脚注阐明这一点:

It is permitted to create a pointer to a va_list and pass that pointer to another function, in which case the original function may make further use of the original list after the other function returns.

我相信行为也是 C90 中的意图,即使标准没有注意到它。 C90 基本原理文档确实是这样说的:

The va_list type is not necessarily assignable. However, a function can pass a pointer to its initialized argument list object, as noted below.

...

va_start must be called within the body of the function whose argument list is to be traversed. That function can then pass a pointer to its va_list object ap to other functions to do the actual traversal. (It can, of course, traverse the list itself.)

很清楚,我认为,通过指针访问 va_list 对象就像您期望的那样(va_list 状态在对象中维护地址取自的实例),即使它没有明确声明原始 va_list 对象将从指针使用停止的地方开始。如果它不能以这种方式工作,指向 va_list 对象的指针的行为必须不同于指向其他 C 对象的指针。

关于c - C 中的可变参数函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20029118/

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