283

Consider these two function definitions:

void foo() { }

void foo(void) { }

Is there any difference between these two? If not, why is the void argument there? Aesthetic reasons?

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
Landon
  • 15,166
  • 12
  • 37
  • 30

4 Answers4

358

In C:

  • void foo() means "a function foo taking an unspecified number of arguments of unspecified type"
  • void foo(void) means "a function foo taking no arguments"

In C++:

  • void foo() means "a function foo taking no arguments"
  • void foo(void) means "a function foo taking no arguments"

By writing foo(void), therefore, we achieve the same interpretation across both languages and make our headers multilingual (though we usually need to do some more things to the headers to make them truly cross-language; namely, wrap them in an extern "C" if we're compiling C++).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
DrPizza
  • 17,882
  • 7
  • 41
  • 53
  • 13
    But if C++ had required the `void`, then it could have avoided the "most vexing parse" problem. – Adrian McCarthy Jan 04 '10 at 17:47
  • 7
    True, but there are so many other crappy parses in C++ there's no real point in kvetching about any one of them. – DrPizza Jan 04 '10 at 18:49
  • 16
    On a recent question, @James Kanze posted an interesting tidbit. Repost here to avoid losing it: the first versions of C did not allow to specify the number of parameters a function might take, thus `void foo()` was the only syntax to declare a function. When signatures where introduced, the C committee had to disambiguate the no-parameter from the old syntax, and introduced the `void foo(void)` syntax. C++ took it for the sake of compatibility. – Matthieu M. Sep 14 '11 at 08:14
  • 3
    Can you give me an example of C C90 and later where using `void foo()` instead of `void foo(void)` will produce a functional difference? I.e. I have been using the version without the void for many years and havent seen any problem, am I missing something? – chacham15 Nov 07 '11 at 08:30
  • Ok, I understand a difference now, but what I will gain in C if I write void foo( void ) instead void foo() ? What is a practical reason to write void explicitly? – unresolved_external Feb 01 '12 at 16:04
  • 1
    You'll receive warnings, if not errors, if you ever mistakenly try to pass args to a no-args function. – DrPizza Feb 02 '12 at 16:16
  • 1
    I now understand why void might be placed in a non parameter accepting function. So would it be best practice to do so in all C++ functions that have no parameters? – Paul Renton Aug 16 '13 at 02:14
  • @AdrianMcCarthy: MVP is hardly a "problem". – Lightness Races in Orbit May 30 '14 at 14:55
  • @AdrianMcCarthy I don't think MVP would've been solved. What about `std::vector v(std::vector());` or any combination of 2 types, constructing one directly in the constructor of the other. – Yam Marcovic May 27 '15 at 11:49
  • 12
    @chacham15 `void foo() { if ( rand() ) foo(5); }` compiles and runs (causing undefined behaviour unless you're very lucky), whereas `void foo(void)` with the same body would cause a compilation error. – M.M Dec 22 '15 at 22:35
  • 1
    @MatthieuM. that is an interesting piece of information. I would love to have a link to read the question/text that you mention. Yeah, I know, 7 years later haha – JohnTortugo Mar 25 '18 at 05:57
  • extern "C" void foo(void) is NOT required, since functions are extern by default and by the very nature of it :) – Sammy Aug 02 '18 at 09:47
  • 1
    If you want your C++ compiler to apply C name mangling rules to C declarations--and you do, if you want the linker to know what you're talking about--then you need `extern "C"` around the C names. – DrPizza Aug 10 '18 at 18:47
  • @M.M You can't "cause" undefined behaviour. Either the program has well-defined behaviour, or it does not. It's a property, not an event. However, whether you see "strange things happening" as a result of executing a program whose behaviour is undefined is down to chance; perhaps that's what you meant? – Asteroids With Wings Jan 21 '21 at 17:07
  • 1
    @AsteroidsWithWings It can be both. Another similar example to the above is `if (getchar() == 'x') 1/0;` , the behaviour is only undefined if execution reaches this line, and certain input is given. – M.M Jan 21 '21 at 20:44
  • @M.M It's still a property of the program; it seemed you were conflating "undefined behaviour" with "possible strange symptoms of undefined behaviour", since you posited the idea that you could somehow avoid it by being "very lucky" (which isn't true in the given example unless the source code changes!) – Asteroids With Wings Jan 21 '21 at 20:45
  • @AsteroidsWithWings The "lucky" element depends on the return value of `rand()`; if it happens to return `0` then there is no undefined behaviour: having `foo(5)` in code that is never executed does not imply the program has UB. I'm not conflating UB with symptoms of UB. Maybe the `getchar()` example is better than the `rand()` example to demonstrate this point in order to avoid arguments about guarantees of the sequence of numbers generated by `rand()` – M.M Jan 21 '21 at 20:51
  • @M.M. Oh, fair :P – Asteroids With Wings Jan 21 '21 at 20:55
42

I realize your question pertains to C++, but when it comes to C the answer can be found in K&R, pages 72-73:

Furthermore, if a function declaration does not include arguments, as in

double atof();

that too is taken to mean that nothing is to be assumed about the arguments of atof; all parameter checking is turned off. This special meaning of the empty argument list is intended to permit older C programs to compile with new compilers. But it's a bad idea to use it with new programs. If the function takes arguments, declare them; if it takes no arguments, use void.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kyle Cronin
  • 77,653
  • 43
  • 148
  • 164
  • 1
    But the question is about definitions, in that case the relevant C rule is _An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters._ – jinawee Dec 26 '18 at 12:56
10

C++11 N3337 standard draft

There is no difference.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

Annex C "Compatibility" C.1.7 Clause 8: declarators says:

8.3.5 Change: In C ++ , a function declared with an empty parameter list takes no arguments. In C, an empty parameter list means that the number and type of the function arguments are unknown.

Example:

int f();
// means int f(void) in C ++
// int f( unknown ) in C

Rationale: This is to avoid erroneous function calls (i.e., function calls with the wrong number or type of arguments).

Effect on original feature: Change to semantics of well-defined feature. This feature was marked as “obsolescent” in C.

8.5.3 functions says:

4. The parameter-declaration-clause determines the arguments that can be specified, and their processing, when the function is called. [...] If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list.

C99

As mentioned by C++11, int f() specifies nothing about the arguments, and is obsolescent.

It can either lead to working code or UB.

I have interpreted the C99 standard in detail at: https://stackoverflow.com/a/36292431/895245

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • The syntax highlighting is off near "means int". Can you fix it? For instance, turned off inside comments or "void" more like [here](https://stackoverflow.com/questions/693788/is-it-better-to-use-c-void-arguments-void-foovoid-or-not-void-foo/693794#693794). – Peter Mortensen Nov 12 '21 at 04:37
3

In C, you use a void in an empty function reference so that the compiler has a prototype, and that prototype has "no arguments". In C++, you don't have to tell the compiler that you have a prototype because you can't leave out the prototype.

Adam Tyszecki
  • 49
  • 1
  • 5
Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • 2
    "prototype" means the argument list declaration and return type. I say this because "prototype" confused me as to what you meant at first. – Zan Lynx Oct 01 '08 at 19:48