Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is void f(...) not allowed in C?

Why doesn't C allow a function with variable length argument list such as:

void f(...)
{
    // do something...
}
like image 340
Rajendra Uppal Avatar asked Jul 04 '11 10:07

Rajendra Uppal


People also ask

Does void exist in C?

Yes, it does exist and hence the compiler is reporting error on this statement. The void in parameter list indicates that function will not take any argument because it has been declared with no parameters.

Can void function have parameters C?

In computer programming, when void is used as a function return type, it indicates that the function does not return a value. When void appears in a pointer declaration, it specifies that the pointer is universal. When used in a function's parameter list, void indicates that the function takes no parameters.

What is a void function in C?

By Dinesh Thakur. Functions may be return type functions and non-return type functions. The non-return type functions do not return any value to the calling function; the type of such functions is void. These functions may or may not have any argument to act upon.

Can we declare variable of void type?

You cannot declare a variable of type void , but you can explicitly convert any expression to type void . The resulting expression can only be used as one of the following cases: An expression statement. The left operand of a comma expression.


2 Answers

I think the motivation for the requirement that varargs functions must have a named parameter is for uniformity of va_start. For ease of implementation, va_start takes the name of the last named parameter. With a typical varargs calling convention, and depending on the direction arguments are stored, va_arg will find the first vararg at address (&parameter_name) + 1 or (first_vararg_type*)(&parameter_name) - 1, plus or minus some padding to ensure alignment.

I don't think there's any particular reason why the language couldn't support varargs functions with no named parameters. There would have to be an alternative form of va_start for use in such functions, that would have to get the first vararg directly from the stack pointer (or to be pedantic the frame pointer, which is in effect the value that the stack pointer had on function entry, since the code in the function might well have moved the sp since function entry). That's possible in principle -- any implementation should have access to the stack[*] somehow, at some level -- but it might be annoying for some implementers. Once you know the varargs calling convention you can generally implement the va_ macros without any other implementation-specific knowledge, and this would require also knowing how to get at the call arguments directly. I have implemented those varargs macros before, in an emulation layer, and it would have annoyed me.

Also, there's not a lot of practical use for a varargs function with no named parameters. There's no language feature for a varargs function to determine the type and number of variable arguments, so the callee has to know the type of the first vararg anyway in order to read it. So you might as well make it a named parameter with a type. In printf and friends the value of the first parameter tells the function what the types are of the varargs, and how many of them there are.

I suppose that in theory the callee could look at some global to figure out how to read the first argument (and whether there even is one), but that's pretty nasty. I would certainly not go out of my way to support that, and adding a new version of va_start with extra implementation burden is going out of my way.

[*] or if the implementation doesn't use a stack, to whatever it uses instead to pass function arguments.

like image 94
Steve Jessop Avatar answered Nov 15 '22 00:11

Steve Jessop


With variable-length argument list you must declare the type of the first argument - that's the syntax of the language.

void f(int k, ...)
{
    /* do something */
}

will work just fine. You then have to use va_list, va_start, va_end, etc. inside the function to access individual arguments.

like image 23
Aleks G Avatar answered Nov 14 '22 23:11

Aleks G