Question

There are a few legal ways which can we declare a function in C++.

Some of the legal ways are:

void function ();
void function (void);
dataType function (dataType);

and so on...

Recently, I came across a function declaration as such:

void (function) ();  //Take note of the braces around the function name

I have never seen somehting like this before, when I tested it in a C++ compiler, it runs without any warning or compilation errors.

My question is: Why is void (function) (); a legal way to decalre a function prototype? Is there any special meaning to declare a function in this way? Or does it just work normally like any other function declaration?

Was it helpful?

Solution

One difference is that enclosing it in parenthesis prevents the function-like macros expansion by the preprocessor. As mentioned in the other answers it makes no difference though to the actual compiler.

For instance:

// somewhere buried deep in a header
#define function(a, b) a + b

// your code
void function() {  // this expands the macro and gives compilation error
}

void (function)() { // this does not expand and works as expected
}

This comes in handy for instance when the bright minds behind the Microsoft Visual Studio library decided to provide function-like macros for things like min and max. (There are other ways like #undef to go around this).

Note that object-like macros (e.g. #define function 3 + 4) are still expanded.


The preprocessor is just a dumb text replacement tool (as opposed to the compiler which is just a (smart) text replacement tool). It takes the macro definition and replaces it everywhere. He is not aware of the semantics of what he replaces.

For instance:

// somewhere buried deep in a header
#define function 3 + 2

// your code
void function() {
}

The preprocessor sees the word function and textually replaces it with the string 3 + 2. He is unaware that function is a id-name part of a function declaration and definition. After the preprocess phase there come the actual compile phases. So the compiler actually sees:

// your code
void 3 + 2() {
}

which does not make any sense to him and gives an error.

For function-like macros

// somewhere buried deep in a header
#define function(a, b) a + b

The preprocessor does the same except that it expects two ‘tokens’ enclosed in parenthesis separated by comma (the parameters) and does the replacement. (again no semantics aware):

int d = function(2, 3);
//will be replaced by the preprocessor to:
int d = 2 + 3; // passes compilation phase

void function();
// the preprocessor doesn’t find the arguments for function so it gives an error.

However if it encounters (function) it will not try to expand it (it ignores it). It is just a rule.

OTHER TIPS

it's the same as

void function();

you can declare it as

void ((function)) ();

if you want :)

be careful not to mix this up with the function pointer declaration syntax.

There is nothing special about it, it means exactly the same as the version without parentheses. It is just an artifact of how the syntax is declared. Usually you see the use of parentheses around the function name when a function pointer is declared, e.g.

void (*function_pointer)() = nullptr;
// a function pointer to a function taking and returning void

in contrast to

void *function();
// a function declaration of a function taking void and returning void*

I think it works the same as a normal function because function pointers are declared like: void (*function)() so if you leave out the * then it should be just a function.

It corresponds to the C++ grammar. If to simplify then one of the rules for defining of the declarator looks as

declarator:

   (declarator)

So you can write for example

void (function) (); 

or

void ( (function) () );

or even the following way

struct A
{
   void ( ( function )() const );
};   

I think you may find that was:

void (*function) ();

since there is no benefit to using void (function)(); or void (((((function)))))(); for that matter, they're equivalent. If I'm mistaken and it's not a typo, the answer is that you can put as many parentheses around the function name as you like, subject to compiler limitations, as per the code for output6() below.

If I'm not mistaken, that one with the * actually declares a function pointer which can be used to hold a pointer to a function. It does not declare a function at all, just a pointer that can be used to reference a function.

Like an int pointer (for example), the function pointer can point to an arbitrary function, parameters notwhithstanding.

So for example:

#include <iostream>

void (((((output6)))))() { std::cout << 6; }
void output7() { std::cout << 7; }
void output8() { std::cout << 8; }
void (*fn)();

int main() {
    fn = &output6; fn();
    fn = &output7; fn();
    fn = &output8; fn();
    std::cout << '\n';
}

would output 678.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top