2

I hope my formatting etc. is ok as this is the first time I post a question. Anyways, I'm searching and couldn't find an explanation why the two different function definitions/declarations are equivalent to each other:

#include <iostream> 

using namespace std;

int quadrat( int x )
{
    return x*x;
}

void printTable_1( int start, int end, int step, int (*func)( int x ) )
{
    for ( int i = start; i <= end; i+=step )
    {
        cout << i << "\t" << func(i) << '\n';
    }
}

void printTable_2( int start, int end, int step, int func( int x ) )
{
    for ( int i = start; i <= end; i+=step )
    {
        cout << i << "\t" << func(i) << '\n';
    }
}
    
int main()
{
    printTable_1(1,10,1,quadrat);
    printTable_2(1,10,1,quadrat);

    return 0;
}

What I don't understand is that I didn't explicitely defined in the function "printTable_2" a function pointer like in the function "printTable_1" and it still expects one. Thanks in advance for the answers!

abg1984
  • 21
  • 1
  • 2
    `int func(int)` as an argument is very much similar to declaring an "array" argument (e.g. `int a[]`) in that the compiler treats it as a pointer. – Some programmer dude Sep 01 '20 at 07:04
  • 1
    if you look at the assembly code you will see that both are translate to function ptr [godbold](https://godbolt.org/z/4n3dfW) – yaodav Sep 01 '20 at 07:06
  • https://stackoverflow.com/a/9413/13071379 may be this answere could ease out things for you – Umar Farooq Sep 01 '20 at 07:07
  • https://en.cppreference.com/w/cpp/utility/functional/function – Jesper Juhl Sep 01 '20 at 07:16
  • 1
    @UmarFarooq it doesn't seem like the answer in your link is quite relevant, but [this](https://stackoverflow.com/a/53503192/7426641) answer to the same question does. – Benny K Sep 01 '20 at 07:23
  • @Someprogrammerdude, that's what I was also thinking. However, I wanted to find proof of it in the standard which I found in the link posted by Benny K. – abg1984 Sep 01 '20 at 08:11
  • 1
    @yaodav, nice website! Very cool to quickly look at the assembly code. – abg1984 Sep 01 '20 at 08:19

1 Answers1

0

Both definitions are the same to the compiler. A rough overview about this behavior can be found in the book Effective STL starting at Page 20 or PDF Page 26.

Let's now look at three more function declarations. The first one declares a function g taking a parameter that's a pointer to a function taking nothing and returning a double:

int g(double (*pf)());

Here's another way to say the same thing. The only difference is that pf is declared using non-pointer syntax (a syntax that's valid in both C and C++):

int g(double pf()); // same as above; pf is> implicitly a pointer 

As usual, parameter names may be omitted, so here's a third declaration for g, one where the name pf has been eliminated:

int g(double ()); // same as above; parameter name is omitted

So in your example we have

int (*func)( int x )

and

int func( int x )

As you can see it is the same way as in the example, where we can just omit the parentheses around func and the *. It is still exactly the same to the compiler in the end.

Nopileos
  • 1,976
  • 7
  • 17
  • Thanks for the answer. Through testing it, I as already aware that both variants work. Then I started searching for validation to find a statement about it in the standards but couldn't find anything why I posted the question. – abg1984 Sep 01 '20 at 08:17