While reviewing code for the KIARA project I came across a change set which read like this:
- void super_duper_func () { + void super_duper_func (void) {
I was puzzled, what’s the difference anyway except from making it explicitly clear that there are no parameter expected? Well, I was wrong. The ISO 9899 standard (read: C99 standard) states under paragraph ‘6.7.5.3 Function declarators (including prototypes)’ that
10 — The special case of an unnamed parameter of type void as the only item in the list
specifies that the function has no parameters.
14 — An identifier list declares only the identifiers of the parameters of the function. An empty
list in a function declarator that is part of a definition of that function specifies that the
function has no parameters. The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied.
Therefore we can conclude that even though your code may compile and work correctly, your code is not standard compliant and you may even leap a compile time error detection. Have a look a this snippet which compiled flawless with clang 3.4:
#include void func(); int main() { func("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); return 0; } void func() { printf("in func()\n"); }
Though when you turn on all warnings in clang you will get a warning but this is easily overlooked and not very obvious:
$ clang -std=c99 -Weverything -o empty_param_list empty_param_list.c empty_param_list.c:10:6: warning: no previous prototype for function 'func' [-Wmissing-prototypes] void func() { ^ empty_param_list.c:3:6: note: this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function void func(); ^ void 1 warning generated.
If you go through the code you will find a function prototype and you may think that if there was no previous prototype and the function is defined later than ‘main’ the compiler will fail anyway … In this case if you forgot the function prototype the compiler would throw an error (conflicting types for ‘func’) even if you passed no arguments.
To sum it up:
- Create function prototypes/declarations (they go before the first function definition in your source)
- If you don’t need any parameters explicitly write void in the parameter list (helps you with finding mistakes)
- Turn on all warnings with either ‘-Wall’ (gcc) or ‘-Weverything’ (clang) and don’t ignore those warnings!
Before C99, the situation was different. In C90
void f();
is a function declaration with unspecified number and types of parameters. Thus, after this declaration, it is legal C to call f with
f(5);
or
f(3.141);
or
f(“hello world!”);
This is not particular type-safe, so it was changed from C90 -> C99.
The safe and always working way is therefore to always specify “void” as function parameter if a function has no parameters in C. However, in C++ an empty set of parenthesis has always (i.e. from the very first C++ 98 standard) meant the same as if written “void”, so it is safe to omit it. Unfortunately, some people mix C and C++ and don’t pay attention that those are in fact two different languages.
See also:
http://stackoverflow.com/questions/18378993/c-and-defining-a-function-prototype-with-no-parameters