25

In C++11 the following function declaration:

int f(void);

means the same as:

int f();

A parameter list consisting of a single unnamed parameter of non-dependent type void is equivalent to an empty parameter list.

I get the (perhaps false) impression this is an old feature, perhaps inherited from C?

Does anyone know the history or rationale behind this way to declare a function with no parameters?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
  • 4
    Which one seems unusual? Both appear to be perfectly logical to me. –  Aug 22 '13 at 09:39
  • @H2CO3: Removed subjective "seemingly unusual". – Andrew Tomazos Aug 22 '13 at 09:40
  • 4
    It's a C++ thing. In C a function declaration without any arguments (not even `void`) has an unspecified number and types of arguments. – Some programmer dude Aug 22 '13 at 09:41
  • @userXXX That wasn't my concern :) You may have a different mind than mine. I was honestly interested in **which** one you were referring to. –  Aug 22 '13 at 09:41
  • @H2CO3: In 99.9% of cases in C++ code a function with no arguments is declared `f()`, so obviously I mean the first one `f(void)`, as stated in the title. – Andrew Tomazos Aug 22 '13 at 09:42
  • @user1131467: Im not sure the question, the rationale is that it came from C. IIRC bjarne wanted to get rid of it but couldn't to be compatible with C code (Ill have to look for a quote though). – Jesse Good Aug 22 '13 at 09:45
  • `f()` seems more logical to me. The absence of parameters is nothing to write there.. – Neil Kirk Aug 22 '13 at 11:37
  • The `()` syntax mean ing "unspecified parameters" in C is a part of K&R syntax. http://stackoverflow.com/q/1630631/187690. That's the history and rationale you requested. – AnT stands with Russia Mar 18 '17 at 14:57

5 Answers5

23

In C++ they both mean the same thing.

In C f(void) is different from f(), becuse f() means "unspecified parameters" - you can legally pass anything (whether the function at receiving the data is happy about that or not is another matter).

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Well, if parameters don't exist in the prototype, how can they be accessed from the function? In the blind assuming the calling convention? Or? – dtech Aug 22 '13 at 10:22
  • The receiving function would have a parameter. The most typical use for this (in modern C) is to allow for variable parameters in function pointers. If `f` is a function pointer, we could have `if (a == 2) f(1, 2); else f(1, 2, 3);` - where the recieving `f` function is defined as `ab(int x, int y);` and `abc(int x, int y, int z);`. – Mats Petersson Aug 22 '13 at 10:26
  • 4
    @ddriver actually it was to allow compatibility with very old c-syntax that allowed to declare functions like `void func() int a; int b; { };`. – RedX Aug 22 '13 at 12:56
11

In C++ both are the same thing.

In C, f() means that we don't know how many parameters the function takes at this point. It is unspecified parameters. And f(void) means that this function does not take any parameters.

From the C standard :

6.7.6.3 Function declarators (including prototypes)

6/ A parameter type list specifies the types of, and may declare identifiers for, the parameters of the function.

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.

And like you said, in the C++ standard :

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 type void is equivalent to an empty parameter list.

Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62
3

This comes to C++ from C. In C f() means unknown number and type of parameters. So in C for no parameters there is f( void ).

In C++ it's redundant: f() and f( void ) mean same thing - a function that has no parameters.

lapk
  • 3,838
  • 1
  • 23
  • 28
1

In C++, there is no difference. However, this is inherited from C, where int f() mean "function which can take any number of arguments of any types" and int f(void); specifies functions that takes no arguments.

Edit As Angew pointed out, in C, f() means "function whose parameters are unknown at this point." It does not mean it can take any number of arguments - close to that would be f(T arg, ...), where arg is at least one named parameter before ..., which accepts at least one argument, arg (as pointed by @hvd).

Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91
  • and any type of arguments. – Uchia Itachi Aug 22 '13 at 09:41
  • Not quite. In C, `f()` means "function whose parameters are unknown at this point." It does not mean it can take any number of arguments - that would be `f(...)`. You can *give it* any number of arguments, but if you don't give it what it expects, it will probably choke on them. – Angew is no longer proud of SO Aug 22 '13 at 09:49
  • C doesn't have any way of specifying that a function can take any number of arguments. C++ allows `f(...)`, but C requires at least one named parameter before that. –  Mar 18 '17 at 13:41
1

From "A History of C++" (1979− 1991 by Bjarne Stroustrup) at p11:

C with Classes introduced the notation f(void) for a function f that takes no arguments as a contrast to f() that in C declares a function that can take any number of arguments of any type without any type check.

It says later, however, that soon the empty function declarator was given its obvious meaning and the new construct - kinda rendered obsolete for the time. I guess nobody has bothered removing it after (or maybe there had been already some C++ code written with it that have needed support).

In C:

This construct however rendered important role as of the standardization of the C language where function prototyping was borrowed directly from C++. In this case f(void) was useful in supporting existing C code (in which the notion f() was already reserved as to indicate a function taking unspecified number of arguments).

Before that the C language hadn't been able to attach specific types to each parameter but only functions with unspecified number of arguments and with unspecified types were declarable using the f() form.

AnArrayOfFunctions
  • 3,452
  • 2
  • 29
  • 66
  • "thus rendering the new construct obsolete" -- Not exactly. It's still important for header files that are meant to be valid in both C and C++ that there is a "takes no parameters" syntax that works in both languages. Removing support for `f(void)` from C++ would break such headers, and there are a lot of them. –  Mar 18 '17 at 13:46
  • @hvd For the time it was (the C++ language being invented) I doubt the C standard was even out yet. I wrote the C part after. – AnArrayOfFunctions Mar 18 '17 at 13:46
  • @hvd The thing is C standardization process copied function prototyping directly from C++ so before that `C` didn't have typed parameters and so the argument of 'compatibility' as a reason for keeping the construct back then could apply only to recently written C++ code with it at the time. – AnArrayOfFunctions Mar 18 '17 at 13:52
  • If you're saying that `f(void)` was rendered obsolete at a time where C did not support `f(void)` yet, then that could be right (I'm not too sure on the history myself), but that's not clear to me from your answer. It read and still reads to me as if you're saying `f(void)` is obsolete even now. –  Mar 18 '17 at 14:01