I have heard that it is a good practice to write functions that do not receive anything as a parameter like this:
int func(void);
But I hear that the right way to express that is like this:
int func();
What is the difference between these two function declarations in both C and C++?
-
6This is a duplicate of a thousand other questions on the site network, among others stackoverflow.com/questions/18167390/…Lars Viklund– Lars Viklund2015年06月11日 15:20:11 +00:00Commented Jun 11, 2015 at 15:20
-
2@LarsViklund it is only a duplicate if there is a question on this site. I cannot find one, so regardless of what is on SO, this is not a duplicate. Probably worth keeping this question around as a signpost if nothing else.user22815– user228152015年06月11日 15:37:34 +00:00Commented Jun 11, 2015 at 15:37
-
16Related question: Understanding the difference between f() and f(void) in C and C++ once and for alluser22815– user228152015年06月11日 15:46:37 +00:00Commented Jun 11, 2015 at 15:46
-
1@LightnessRacesinOrbit we discussed in chat and decided to keep it around with some edits.user22815– user228152015年06月11日 16:59:36 +00:00Commented Jun 11, 2015 at 16:59
-
stackoverflow.com/questions/693788/… | stackoverflow.com/questions/51032/… | stackoverflow.com/questions/416345/…Ciro Santilli OurBigBook.com– Ciro Santilli OurBigBook.com2016年04月25日 08:38:35 +00:00Commented Apr 25, 2016 at 8:38
2 Answers 2
C and C++ are different in this respect.
6.7.6.3 Function declarators (including prototypes)
...
10 The special case of an unnamed parameter of typevoid
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.145)
In short, an empty parameter list in a function declaration indicates that the function takes an unspecified number of parameters, while an empty parameter list in a function definition indicates that the function takes no parameters.
T foo( void ); // declaration, foo takes no parameters
T bar(); // declaration, bar takes an *unspecified* number of parameters
T foo( void ) { ... } // definition, foo takes no parameters
T bar() { ... } // definition, bar takes no parameters
As far as C is concerned, you should never use an empty identifier list in a function declaration or definition. If a function is not meant to take any parameters, specify that by using void
in the parameter list.
8.3.5 Functions [dcl.fct]
...
4 The parameter-declaration-clause determines the arguments that can be specified, and their processing, when the function is called. [ Note: the parameter-declaration-clause is used to convert the arguments specified on the function call; see 5.2.2. — end note ] If the parameter-declaration-clause is empty, the function takes no arguments. A parameter list consisting of a single unnamed parameter of non-dependent typevoid
is equivalent to an empty parameter list. Except for this special case, a parameter shall not have typecv void
. If the parameter-declaration-clause terminates with an ellipsis or a function parameter pack (14.5.3), the number of arguments shall be equal to or greater than the number of parameters that do not have a default argument and are not function parameter packs. Where syntactically correct and where "..." is not part of an abstract-declarator, ", ..." is synonymous with "...". [Example: the declarationdeclares a function that can be called with varying numbers and types of arguments.int printf(const char*, ...);
However, the first argument must be of a type that can be converted to aprintf("hello world"); printf("a=%d b=%d", a, b);
const char*
— end example ] [ Note: The standard header<cstdarg>
contains a mechanism for accessing arguments passed using the ellipsis (see 5.2.2 and 18.10). — end note ]
In the case of C++, an empty parameter list in either a declaration or a definition indicates that the function takes no arguments, and is equivalent to using a parameter list of void
.
In C, a function with an empty parameter list ()
can take anything for its arguments. Literally anything. This is usually used to implement a function which can take a variable number of arguments, though these days it's considered preferable to use the more explicit ellipsis syntax (...)
for these functions.
In C, a function with the parameter list (void)
explicitly takes nothing for its arguments. That means the compiler can actually tell you you've made a mistake if you try to pass something.
In C++, these function declarations are equivalent. A blank parameter list means "no parameters" the same as void
does.
-
1Re: "This is usually used to implement a function which can take a variable number of arguments": Are you sure about this? I don't think I've ever seen a program that used explicit parameter-lists for forward-declarations of non-variadic functions and
()
for those of variadic ones. Do you have an example of a program that uses this convention?ruakh– ruakh2015年06月12日 00:46:01 +00:00Commented Jun 12, 2015 at 0:46 -
5A C variadic function must be defined with the
...
syntax, and it must have at least one named parameter. Defining such a function with()
causes undefined behavior -- and there's no way for the body of the function to use the macros defined in<stdarg.h>
to read the parameter values. This has been the case since the 1989/1990 standard.Keith Thompson– Keith Thompson2015年06月16日 20:56:26 +00:00Commented Jun 16, 2015 at 20:56 -
@KeithThompson: This question, and this answer, are talking about predeclarations, not function definitions.ruakh– ruakh2015年07月05日 00:01:22 +00:00Commented Jul 5, 2015 at 0:01
-
4@ruakh: A variadic function must be declared and defined using the
...
syntax to avoid undefined behavior.Keith Thompson– Keith Thompson2015年07月05日 06:42:11 +00:00Commented Jul 5, 2015 at 6:42