使用C89可变参数的函数而不传递参数的数目或最终的说法? [英] Use variadic functions in C89 without passing number of arguments or a final argument?

查看:182
本文介绍了使用C89可变参数的函数而不传递参数的数目或最终的说法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一个可变参数函数美孚(INT TMP,...),调用foo函数时,我需要知道有多少争论有。我所知道的找出两种方法有多少参数有:

Let's say I have a variadic function foo(int tmp, ...), when calling foo function I need to know how many arguments there are. I'm aware of two ways of finding out how many arguments there are:


  1. 调用foo时,像-1使用最后一个参数,所以你的函数调用将是这样的:美孚(TMP,1,2,9,-1),当你在里面foo和一个在va_arg调用返回-1你知道你已经阅读所有的函数参数

  1. Use a final argument when calling foo, like -1, so your function call will be like this: foo(tmp, 1, 2, 9, -1) and when you are inside foo and a va_arg call returns -1 you know you have read all the function arguments

添加的富多了一个参数,其中程序员将有参数的总数,所以你将不得不调用到foo这样的:美孚(TMP,5,1,2,3 ,4,5)美孚(TMP,2,7,8)

Add one more argument in foo where the programmer will have the total number of arguments, so you will have calls to foo like this: foo(tmp, 5, 1, 2, 3, 4, 5) or foo(tmp, 2, 7, 8)

我曾经跟随第一种方式,一旦有以下错误。随着code:

I used to follow the first way and once had the following bug. With the code:

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

在这里expr_of_type是一个可变参数函数,是检查是否EXPR(第一个参数)是下列类型之一(boolexpr_e或new_table_e或nil_e拥有所有类型枚举类型)。
我合一无意中写道:

where expr_of_type was a variadic function and was checking if expr(the first argument) was one of the following types (boolexpr_e or new_table_e or nil_e had all type of an enumerated type). I one accidently wrote:

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

我忘了nil_e和-1之间的逗号,因为nil_e有一个枚举类型,nil_e - 1是一个有效的前pression因为nil_e不是0试图让expr_of_type参数没有当给定的可变参数函数找到-1作为最后一个参数,并继续寻找创造这我花了一些时间去找出一个bug。

I forgot the comma between nil_e and -1, because nil_e had an enumerated type, nil_e - 1 was a valid expression and because nil_e was not 0 the given variadic function when trying to get expr_of_type arguments didn't find -1 as last argument and continued searching creating a bug which took me some time to find out.

我没有找到很好的第二种方式要么,因为添加或从可变参数函数删除多一个说法,当您需要更改包含总参数的数量参数。

I don't find the second way nice either, because when adding or removing one more argument from a variadic function you need to change the parameter that contains the number of total arguments.

在寻找一种更好的方式来使用/创建可变参数的功能,我发现复杂的宏从而可以解决我用第一种方式,当有错误。但是复杂的宏可用于C99的标准。我一直在寻找更好的方法来使用/ C89中创建可变参数的函数。任何想法?

In searching for a better way to use/create variadic functions I found variadic macros which can solve the bug I had when using the first way. But variadic macros are available to C99 standard. I was looking for a better way to use/create variadic functions in C89. Any ideas?

推荐答案

在一般情况下,你仍然必须沿着参数传递计数不知何故,无论是通过的警戒值或通过明确的数量。

In general, you must still pass along the argument count somehow, whether via a sentinel value or via an explicit count.

您可以,但是,通过更好的定点解决您的定点问题。这就是为什么扩大到负常量preprocessor宏应该在括号包围的原因之一:

You could, however, fix your sentinel problem by making a better sentinel. This is one of the reasons why preprocessor macros that expand to negative constants should be surrounded in parentheses:

#define VARARG_SENTINEL (-1)

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

使用枚举 const int的将工作太:

enum { VARARG_SENTINEL = -1 };

使用符号常量的标记值将是其他原因也更好(更自我记录,便于以后更改基础值)。

Using a symbolic constant for the sentinel value would be better for other reasons too (more self-documenting, easier to change the underlying value later).

这篇关于使用C89可变参数的函数而不传递参数的数目或最终的说法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆