1

As a C++ learner, I came across the following piece of code from C++ Language Tutorial and got two questions, could any expert provide some guidance on those?

#include <iostream>
using namespace std;
int addition (int a, int b)
{ return (a+b); }
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, int
(*functocall)(int,int))
{
  int g;
  g = (*functocall)(x,y);
  return (g);
}
int main () {
  int m,n;
  int (*minus)(int,int) = subtraction;
  m = operation (7, 5, addition);
  n = operation (20, m, minus);
  cout <<n;
  return 0;
}

In function "operation" definition:

Question 1: for "g = (*functocall)(x,y)", does it deference the pointer that points to a function (ex.subtraction) and assign it to g?

Question 2: for "return(g)", I'm wondering why we put parenthesis for g?

And for "int (*minus)(int,int) = subtraction;" in the main function, is that okay if we write the following instead?

int (*minus)(int,int)

minus = subtraction

M00000001
  • 309
  • 2
  • 10
  • Does this answer your question? [Calling C++ class methods via a function pointer](https://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer) – Aditya Deshpande Nov 23 '19 at 04:22
  • Please take a look at our [recommended C++ book list](https://stackoverflow.com/q/388242). Many "C++ language tutorials" are known for sporting glaringly obvious factual errors and promoting abysmally bad programming styles. – L. F. Nov 23 '19 at 04:23

2 Answers2

1

Before I start, your code uses way more parenthesis than it needs.

Here is the same code, better formatted and reduced:

#include <iostream>

using namespace std;

int addition (int a, int b)
{ return a+b; }
int subtraction (int a, int b)
{ return a-b; }
int operation (int x, int y, int (*functocall)(int,int))
{
  int g;
  g = functocall(x,y);
  return g;
}

int main () {
  int m,n;
  int (*minus)(int,int) = subtraction;
  m = operation (7, 5, addition);
  n = operation (20, m, minus);
  cout <<n<<"\n";

  return 0;
}

for "g = (*functocall)(x,y)", does it deference the pointer that points to a function (ex.subtraction) and assign it to g?

In a nutshell - yes. When calling a function through it's pointer, it is not necessary to explicitly dereference it. I know, it's surprising and counter to the way pointers are typically used.

Think of it this way. Whenever you are just writing the name of a function, you are essentially getting the function's pointer. This is why you wrote as you did, rather than write:

  m = operation (7, 5, &addition);

You do not need to explicitly dereference when using a function pointer for the same reason you do not need to explicitly use the address of operator when taking its address in the first place.

Question 2: for "return(g)", I'm wondering why we put parenthesis for g?

There is positively no good reason to. In fact, there is no reason to do it for any of your return statements.

And for "int (*minus)(int,int) = subtraction;" in the main function, is that okay if we write the following instead?

int (*minus)(int,int);
minus = subtraction;

Personally, I recommend you use:

int (*minus)(int,int) = nullptr;
minus = subtraction;

so as not to leave uninitialized variables, but otherwise, yes, absolutely. A pointer to function variable is just like any other variable.

Shachar Shemesh
  • 8,193
  • 6
  • 25
  • 57
1

Question 1: for g = (*functocall)(x,y), does it deference the pointer that points to a function (ex.subtraction) and assign it to g?

Answer: No.

(*functocall)(x,y);

is simply one allowable syntax for invoking the function from the pointer passed as a parameter. It is entirely equivalent to:

functocall(x,y);

Which simply eliminates the (*...) syntax which is allowable but unnecessary.

Question 2: for return(g), I'm wondering why we put parenthesis for g?

The parenthesis too are discretionary and are superfluous to the return. Simply providing:

return g;

is all that is needed as there is no expression requiring evaluation priority provided by the enclosing (..).

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85