Function with 0 arguments - void vs void*?
Asked Answered
R

4

6

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?

Rattlepate answered 28/7, 2020 at 19:16 Comment(9)
I don't ever recall seeing the last one. I expect it will require you passing a pointer to any type.Smallpox
test() and test(void) are equivalent in C++, but not in C. Unless C compatibility is required, the former form should be preferred. The function test(void*) differs from the other two; it takes an unnamed argument of type void*.Mckeever
void is “nothing”, void* is “the location of something”. There’s a big difference between nothing at all and a place.Phio
There's also this Q&A https://mcmap.net/q/1142262/-foo-void-vs-foo-voidOintment
Then shouldn't void* be "the location of nothing"?Rattlepate
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.Heliogabalus
@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.Sure
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().Musick
@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”.)Phio
D
7

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.

Dispend answered 28/7, 2020 at 19:22 Comment(4)
Why is it like this?Rattlepate
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.Drilling
Related to the void pointer: https://mcmap.net/q/187325/-what-is-a-void-pointer-in-c-duplicateSmallpox
'oxymoronic' - Made my day.Rattlepate
M
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?

Macpherson answered 28/7, 2020 at 19:23 Comment(0)
T
4

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
{
    //...
}
Tepic answered 28/7, 2020 at 19:36 Comment(2)
"has 1 parameter, an object of type void * " -- it's not necessarily an objectHeadmistress
@Headmistress 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"Tepic
N
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.

Nailhead answered 28/7, 2020 at 19:27 Comment(3)
"() parameter list declares a function that accepts any number of arguments" could you please expand on that "()"Nonanonage
@RokoC.Buljan It's a leftover from K&R C, where you didn't declare the arguments of a function in the parameter list.Drilling
@RokoC.Buljan I added language rules to expand on it.Nailhead

© 2022 - 2024 — McMap. All rights reserved.