5

I know that you can declare a function without any arguments simply like this:

void test()
{
    cout << "Hello world!!" << endl;
}

But I have also seen

void test(void)
{
    cout << "Hello world!!" << endl;
}

and

void test(void*)
{
    cout << "Hello world!!" << endl;
}

My question is: What is the difference between using void and void* here?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I don't ever recall seeing the last one. I expect it will require you passing a pointer to any type. – drescherjm Jul 28 '20 at 19:19
  • 2
    `test()` and `test(void)` are equivalent in C++, but not in C. Unless C compatibility is required, the [former form should be preferred](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#nl25-dont-use-void-as-an-argument-type). The function `test(void*)` differs from the other two; it takes an unnamed argument of type `void*`. – Brian61354270 Jul 28 '20 at 19:19
  • `void` is “nothing”, `void*` is “the location of something”. There’s a big difference between nothing at all and a place. – molbdnilo Jul 28 '20 at 19:24
  • 1
    There's also this Q&A https://stackoverflow.com/questions/58822654/foovoid-vs-foovoid – StoryTeller - Unslander Monica Jul 28 '20 at 19:25
  • Then shouldn't void* be "the location of nothing"? –  Jul 28 '20 at 19:25
  • 3
    No. `void*` is essentially a typeless pointer, a raw memory address. It can point to any "object." You can set it to `null` to have it point to nothing. – Robert Harvey Jul 28 '20 at 19:26
  • @super, Perhaps, but that's not how it turned out. I don't see how it would justify its existence with that meaning, so it probably provided a lucrative opportunity to reuse syntax. – chris Jul 28 '20 at 19:26
  • `void f(void)` is a C-ism. In C++ you don't need that and wouldn't normally do that. You'd just do `void f()`. – Jesper Juhl Jul 28 '20 at 19:30
  • 1
    @super Like many other things in C and C++, the word “void” means different things depending on context. On its own it means “nothing”, with an added asterisk it means “anything”. (There’s loads of fun when you get to “static” and “operator”.) – molbdnilo Jul 28 '20 at 19:46

4 Answers4

7

The one an only form for a function with no parameters in C++ should be

void test();

The form:

void test(void)

That is how you define a function with no parameters in . But in C++ use this form only for interfacing with :

extern "C"
{
void test(void);
}

This form:

void test(void*)

Is not a function with no arguments. It has an argument of type void* that is unnamed. It expects a void* pointer when called.

Have a look here for an explanation of what a void* pointer is: What does void* mean and how to use it?

bolov
  • 72,283
  • 15
  • 145
  • 224
6

What is the difference between using void and void* here?

When the argument type is void, the function must be called without any arguments.

When the argument type is void*, the function must be called with an argument that is a void* or can be converted to a void*.

void stands for "nothing" but void* does not stand for "pointer to nothing". In fact, it's quite the contrary. void* stands for pointer to anything except void. It is oxymoronic but that's how the language defines those two.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Why is it like this? –  Jul 28 '20 at 19:23
  • `test(void)` is for C compatibility. C needs this for backward compatiiblity with early versions of C that didn't have parameter types in the argument list. – Barmar Jul 28 '20 at 19:24
  • Related to the void pointer: [https://stackoverflow.com/questions/8530080/what-is-a-void-pointer-in-c](https://stackoverflow.com/questions/8530080/what-is-a-void-pointer-in-c) – drescherjm Jul 28 '20 at 19:25
  • 'oxymoronic' - Made my day. –  Jul 28 '20 at 19:30
3

My question is: What is the difference between using void and void* here?

(void) parameter list is same as empty parameter list. The void here does nothing in C++ and is unnecessary unless compatibility with C is needed - see the second part of the answer.

(void*) does not accept 0 arguments. It accepts 1 argument. The type of the parameter is void* which is a pointer type.


Why is it like this?

Because of backwards compatibility with C. In C, (void) is the only way to declare a function that only accepts empty argument list. () parameter list declares any function without specifying the parameters. The number of parameters could be any, including 0. The use of () parameter list in C is becoming an obsolete feature.

Quote from C11 standard draft N1548:

Function declarators (including prototypes)

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.

Future language directions

Function declarators

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

Function definitions

The use of function definitions with separate parameter identifier and declaration lists (not prototype-format parameter type and identifier declarators) is an obsolescent feature.

C is this way because of backward compatibility with older versions (pre-standard) of C where parameter lists weren't declared.

eerorika
  • 232,697
  • 12
  • 197
  • 326
3

In C++ these two declarations of a function

void test();

and

void test(void);

are equivalent and mean that the function does not take any arguments.

In C, the first function declaration declares a function with an empty identifier list, and the second function declaration declares a function with a parameter type list that in fact has no parameters.

According to the C Standard (6.9.1 Function definitions):

5 If the declarator includes a parameter type list, the declaration of each parameter shall include an identifier, except for the special case of a parameter list consisting of a single parameter of type void, in which case there shall not be an identifier. No declaration list shall follow.

This declaration of the function (that is also its definition)

void test(void*)
{
    //...
}

has 1 parameter, an object of type void * (pay attention to that pointers are always complete types), that is not used within the function.

This declaration is valid in C++, and is not valid in C, because in C each function parameter in a function declaration with a parameter type list that is at the same time its definition shall have an identifier, except in the case when a void parameter is used, as specified in the quote above.

In C you may use such a declaration only when the declaration is not at the same type its definition.

So in C for example you may write like

void test(void*); // declaratipon

and then

void test( void *ptr ) // declaration and definition
{
    //...
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • "has 1 parameter, an object of type void * " -- it's not necessarily an object – nicomp Jul 28 '20 at 20:52
  • 1
    @nicomp pointers are objects. For example in C object is defined like "region of data storage in the execution environment, the contents of which can represent values" – Vlad from Moscow Jul 28 '20 at 20:53