gpt4 book ai didi

c - 在不传递参数数量或最终参数的情况下在 C89 中使用可变参数函数?

转载 作者:行者123 更新时间:2023-12-02 07:51:57 24 4
gpt4 key购买 nike

假设我有一个可变参数函数 foo(int tmp, ...),在调用 foo 函数时我需要知道有多少个参数。我知道有两种方法可以找出有多少参数:

  1. 调用 foo 时使用最后一个参数,例如 -1,因此您的函数调用将像这样:foo(tmp, 1, 2, 9, -1) 并且当您在 foo 内并且 va_arg 调用返回 -1 你知道你已经阅读了所有函数参数

  2. 在 foo 中再添加一个参数,程序员将拥有参数总数,因此您将像这样调用 foo:foo(tmp, 5, 1, 2, 3, 4, 5)foo(tmp, 2, 7, 8)

我以前都是按照第一种方式,曾经有过如下bug。使用代码:

expr_of_type(expr, boolexpr_e, newtable_e, nil_e, -1)

其中 expr_of_type 是一个可变参数函数,它正在检查 expr(第一个参数)是否是以下类型之一(boolexpr_e 或 new_table_e 或 nil_e 具有枚举类型的所有类型)。我一个不小心写道:

expr_of_type(expr, boolexpr_e, newtable_e, nil_e -1)

我忘记了 nil_e 和 -1 之间的逗号,因为 nil_e 有一个枚举类型,nil_e - 1 是一个有效的表达式,并且因为 nil_e 不是 0,所以在尝试获取 expr_of_type 参数时给定的可变参数函数没有找到 -1 作为最后一个参数并继续搜索创建了一个错误,我花了一些时间才找到它。

我也不觉得第二种方法好,因为在可变参数函数中添加或删除一个参数时,您需要更改包含参数总数的参数。

在寻找使用/创建可变参数函数的更好方法时,我发现了 variadic macros这可以解决我使用第一种方式时遇到的错误。但是可变参数宏可用于 C99 标准。我一直在寻找一种更好的方法来在 C89 中使用/创建可变参数函数。有什么想法吗?

最佳答案

通常,您仍然必须以某种方式传递参数计数,无论是通过标记值还是通过显式计数。

但是,您可以通过制作更好的哨兵来解决您的哨兵问题。这就是扩展为负常量的预处理器宏应该用括号括起来的原因之一:

#define VARARG_SENTINEL (-1)

然后nil_e VARARG_SENTINEL会产生一个编译错误。

使用 enumconst int 也可以:

enum { VARARG_SENTINEL = -1 };

出于其他原因,使用符号常量作为标记值也会更好(更多的 self 记录,以后更容易更改基础值)。

关于c - 在不传递参数数量或最终参数的情况下在 C89 中使用可变参数函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3272444/

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