开发者

Why variadic functions require at least two arguments?

开发者 https://www.devze.com 2023-04-10 05:37 出处:网络
I\'m trying to plug a hole in my knowledge. Why variadic functions require at least two arguments? Mostly from C\'s mai开发者_StackOverflow中文版n function having argc as argument count and then argv

I'm trying to plug a hole in my knowledge. Why variadic functions require at least two arguments? Mostly from C's mai开发者_StackOverflow中文版n function having argc as argument count and then argv as array of arrays of chars? Also Objective-C's Cocoa has NSString methods that require format as first argument and afterwards an array of arguments ([NSString stringWithFormat:@"%@", foo]). Why is it impossible to create a variadic function accepting only a list of arguments?


argc/argv stuff is not really variadic.

Variadic functions (such as printf()) use arguments put on the stack, and don't require at least 2 arguments, but 1.

You have void foo(char const * fmt, ...) and usually fmt gives a clue about the number of arguments. That's minimum 1 argument (fmt).


C has very limited reflection abilities so you must have some way to indicate what it is that the variable arguments contain - either specifying the number of arguments or the type of them (or both), and that is the logic behind having one more parameter. It is required by the ISO C standard so you can't omit it. If feel you don't need any extra parameters because the number and type of the arguments is always constant then there is no need for variable arguments in the first place.

You could of course design other ways to encode the number / type information inside the variable arguments such as a sentinel value. If you want to do this, you can just supply a dummy value for the first argument and not use it in the method body.

And just to be pedantic about your title, variadic functions only require one argument (not two). It's perfectly valid to make a call to a variadic function without providing any optional arguments:

printf("Hello world");


I think, that the reason is the following: in the macro va_start(list, param); you specify the last fixed argument - it is needed to determine the address of the beginning of the variable arguments list on the stack.


How would you then know if the user provided any arguments?

There has to be some information to indicate this, and C in general wasn't designed to do behind-your-back data manipulation. So anything you need, it makes you pass explicitly.


I'm sure if you really wanted to you could try to enforce some scheme whereby the variadic function takes only a certain type of parameter (a list of ints for example) - and then you fill some global variable indicating how many ints you had passed.

Your two examples are not variadic functions. They are functions with two arguments, but they also highlight a similar issue. How can you know the size of a C array without additional information? You can either pass the size of the array, or you describe a scheme with some sentinel value demarcating the end of the array (i.e. '\0' for a C string).

In both the variadic case and the array case you have the same problem, how can you know how much data you have legitimate access to? If you don't know this with the array case, you will go out of bounds. If you don't know this with the variadic case you will call va_arg too many times, or with the wrong type.

To turn the question around, how would you be able to implement a function taking a variable number of arguments without passing the extra information?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号