Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why void() redefines a function in C++?

Given this function:

int f() {return 10;}

void(f()) defines a void f() and doesn't compile with the following error:

'void f(void)': overloaded function differs only by return type from 'int f(void)'

While if a call expression is used, the code compiles:

void(f(void());

Why is this?

I'm using Microsoft VC++

like image 626
Bagheri Avatar asked Jan 26 '26 22:01

Bagheri


2 Answers

Both the constructions

void(f());

and

void(f(void());

declare functions with the name f. You may enclose declarators in parentheses.

For example your first function could be declared like

int( f() )
{
    return 10;
}

The first construction declares a function that has the return type void and no arguments. So it differs from your first function declaration only by the return type. As result the compiler issues the error message because you may not overload functions that differ only by their return types.

The second construction declares a function that has as its parameter a function of the type void(). So it differs from your first function declaration by the number and type of parameters. So such an overloaded function declaration is valid.

Here is a demonstration program.

#include <iostream>

int f();
void ( f( void() ) );

int f()
{
    return 10;
}

void ( f( void g() ) )
{
    g();
}

void h()
{
    std::cout << "Hello, function declarations!\n";
}

int main() 
{
    f( h );
}

Its output is

Hello, function declarations!

If you want just to cast the result of the function call to void you can write for example

( void )f();
like image 112
Vlad from Moscow Avatar answered Jan 28 '26 13:01

Vlad from Moscow


Sometimes you need parenthesis in a declaration, for example to tell the difference between these:

int* f();     // function returning a pointer to int
int (*f)();   // pointer to function returning an int

Nobody has cared enough to set up the rules of exactly when the set of parenthesis is strictly needed, so the language just says that they are allowed. Even in places where they are not needed.

So, you can write int* f(); or int* (f)(); or int* (f()); or int* ((( f() )));, they all mean the same.

And, according to this, your void(f()); is the same as void (f()); and the same as void f();. It declares a function, but doesn't call it.

like image 27
BoP Avatar answered Jan 28 '26 11:01

BoP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!