Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c - How to determine the end of va_arg list?

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)
{
   ...
}

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); ?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

Your proposed method in particular:

while(va_arg(argPtr, char) != NULL)

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 '', but you can't rely on that.)

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.)

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 ", "hello") or execlp("name", "arg1") have undefined behavior.

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).

(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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...