amrith amrith - 1 month ago 9
C Question

C and defining a function prototype with no parameters

This question is an offshoot of `f(void)` meaning no paramters in C++11 or C?

Several have answered that question and opined that in C, the meaning of the function prototype

void func ()


is that func is a function returning nothing (void) and whose parameters are unknown at this time.

Further they have opined that one could make this declaration and then invoke the function with some arguments such as:

func (1, 2, 3);


So, I did this, I made a test to verify that this works and I'm not surprised that it does.

Here is func.c, which contains
main()


#include <stdio.h>

extern void func ();

int main (int ac, char ** av)
{
func (1, 2, 3);

return 0;
}


And here is func1.c which contains the function
func()


#include <stdio.h>

void func (int a, int b, int c)
{
printf ( "%d, %d, %d\n", a, b, c );
}


And here are my question(s)

Question 1:

When I run this program, I get, as expected the output 1, 2, 3.
Is this a safe way to write code; i.e. can one assume that the ABI will reliably ensure that the invocation of
func()
in
main()
will put the three parameters in the right places (registers, stack, whatever) for
func()
to find them?

Question 2:

If the answer to 1 above is that it is a safe thing to do, then does your answer change if
func()
is implemented in some language other than C?

Answer

Are you asking about C or about C++?

C did not originally have function prototypes. You'd write:

extern void func();

and then define it:

void func( a, b, c )
    int a;
    int b;
    int c;
{
    //  ...
}

C++ added function prototypes, and made the above illegal. And the declaration:

extern void func();

declared a function which had no parameters; calling it with arguments was an error, as was defining it with arguments.

C then added function prototypes from C++. But to avoid breaking existing code, it didn't require them, and treated

extern void func();

as before: a function taking an unknown number and types of parameters. So it also added:

extern void func(void);

as a special way of saying that the function doesn't take any parameters. C++ then added this special case for reasons of C compatibility.

The general rule, in C++, is to just write:

extern void func();

The only time you'd use the form with void is in a header that had to be compatible with both languages. In C, of course, this form doesn't do what you want, so you have to add the void. (For now. From what I understand, C has deprecated the older forms, and so could, in the future, behave exactly like C++ in this respect.)

EDIT:

Having looked it up. From the C11 standard, ยง6.11.6:

The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.

Don't do it in C.

Comments