如何确定 va_arg 列表的结尾? [英] How to determine the end of va_arg list?
问题描述
我有一个函数 foo(char *n, ...);
我需要获取并使用所有可选的 char
参数.我有一个使用
I have a function foo(char *n, ...);
I need to get and use all of optional char
parameters.
I had an idea to use
while(va_arg(argPtr, char) != NULL)
{
...
}
了解我何时到达列表的末尾.那么,它会起作用吗,如果在函数调用中我会做 foo(n, 't', 'm', '$', NULL);
?
to understand when I reach the end of the list. So, will it work, if in function call I'll do foo(n, 't', 'm', '$', NULL);
?
NULL
会被 va_arg 读取为字符吗?或者也许有一种更常见的方法来确定列表的结尾,而不添加 NULL
作为最后一个参数?
Will NULL
be read as a char by va_arg?
Or maybe there's a more common way to determine the end of list, without adding NULL
as last parameter?
推荐答案
对于使用 va_arg
来确定数字或类型的函数没有直接方式) 给定调用传递的参数.
There is no direct way for a function that uses va_arg
to determine the number or type(s) of the arguments passed by a given call.
特别是您提出的方法:
while(va_arg(argPtr, char) != NULL)
不正确.va_arg(argPtr, char)
产生一个 char
类型的值,而 NULL
是一个空指针常量.(NULL
通常定义为 0
,它相当于空字符 '\0'
,但你不能依赖它.)
is incorrect. va_arg(argPtr, char)
yields a value of type char
, while NULL
is a null pointer constant. (NULL
is commonly defined as 0
, which compares equal to the null character '\0'
, but you can't rely on that.)
任何可变参数函数都必须有一种方法让调用者指定参数的数量和类型.例如,*printf
函数通过(非可变参数)格式字符串执行此操作.POSIX execl*()
函数需要一个 char*
参数序列;参数列表的末尾由调用者用 (char*)NULL
标记.其他方法也是可能的,但它们几乎都依赖于运行时参数中给出的信息.(您可以使用其他方法,例如全局变量.请不要.)
Any variadic function must have a way for the caller to specify the number and types of arguments. The *printf
functions, for example, do so via the (non-variadic) format string. The POSIX execl*()
functions expect a sequence of char*
arguments; the end of the argument list is marked by the caller with (char*)NULL
. Other methods are possible, but they almost all depend on information given at run time in the arguments. (You could use some other method, such as a global variable. Please don't.)
这给调用者带来了负担,以确保传递给函数的参数是一致的.函数本身无法确认这一点.不正确的调用,例如 printf("%d\n", "hello")
或 execlp("name", "arg1")
具有未定义的行为.
This places a burden on the caller to ensure that the arguments passed to the function are consistent. The function itself has no way to confirm this. Incorrect calls, like printf("%d\n", "hello")
or execlp("name", "arg1")
have undefined behavior.
还有一点:您不能将 va_arg
与 char
类型的参数一起使用.当你调用一个可变参数函数时,对应于 , ...
的参数被提升.小于 int
类型的整数参数被提升为 int
或 unsigned int
,而 float
类型的参数被提升提升为 double
.如果调用者传递了 char
类型的参数,则该函数必须调用 va_arg(argPtr, int)
.
One more thing: you can't use va_arg
with an argument of type char
. When you call a variadic function, arguments corresponding to the , ...
are promoted. Integer arguments of types narrower than int
are promoted to int
or to unsigned int
, and arguments of type float
are promoted to double
. If a caller passes an argument of type char
, the function must invoke va_arg(argPtr, int)
.
(在您不太可能遇到的非常隐晦的情况下,char
可以被提升为 unsigned int
.只有当纯 char
是无符号的并且 sizeof (int) == 1
,这意味着一个字节至少是 16 位.)
(In very obscure circumstances that you're not likely to run into, char
can be promoted to unsigned int
. That can happen only if plain char
is unsigned and sizeof (int) == 1
, which implies that a byte is at least 16 bits.)
这篇关于如何确定 va_arg 列表的结尾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!