4

Here is three functions such as:-

float Plus    (float a, float b) { return a+b; }
float Minus   (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }

now there is function which takes pointer to a function as one of the argument:-

void Function_Pointer_func(float a, float b, float (*pt2Func)(float, float))
{
   float result = pt2Func(a, b);    // call using function pointer

   cout << " Result = ";  // display result
   cout << result << endl;
}

and to call the above function "Function_Pointer_func" the function is written below

void Replace()
{ 
   Function_Pointer_func(2, 5, /* pointer to function 'Minus' */ Plus);////   (1)
   Function_Pointer_func(2, 5, /* pointer to function 'Minus' */ &Minus);//// (2)

}

Why does above function works fine as function "Function_Pointer_func" takes function-pointer as argument. And if we replace RHS in line

 float result = pt2Func(a, b);    // call using function pointer 

of function "Function_Pointer_func" by (*pt2Func)(a, b);then also it works but for (&pt2Func)(a, b);

it gives an error in VS2008:

" error C2064: term does not evaluate to a function taking 2 arguments "

Now replace in the argument of "float (*pt2Func)(float, float)" in function "Function_Pointer_func" by float (pt2Func)(float, float) then all three

float result = pt2Func(a, b);    // 
float result = (&pt2Func)(a, b); // 
float result = (*pt2Func)(a, b); // 

statement works, why? I hope reason of my discomfort lies in understanding the core understanding of function-pointer. Well, I am not presenting the Q? without any good amount of reading but yes i haven't done any intensive research on this so please feel free to recommend some reading in this regard which will sort out my ambiguity.

Thanks for the help in advance.

2
  • There's already a perfectly good std::plus<float>, no need to write your own. Commented Aug 13, 2013 at 9:12
  • thanks @RiaD for pointing that reason for working all three types may be a bug/feature of msvc. It does lift the wind of doubt but i will see for same with other compiler. Commented Aug 13, 2013 at 19:17

2 Answers 2

2

Functions automatically decay into function pointers. In that context,

  • function_name really means &function_name if not specified.

  • &function_name turns a function into a function pointer.

  • *function_name really means *(function_name), which becomes *(&function_name) per above. * and & "cancel out", so to speak and the resulting function_name decays back into &function_name.

Sign up to request clarification or add additional context in comments.

4 Comments

@jrok ok you say that "Functions automatically decay into function pointers" it clears some of my confusion but still i not free from doubt. As you say in your 3rd statement that *function_name eventually become (&function_name) but what about &function_name. And why if one of the argument in function is (pt2Func)(float, float) then all three types work please comment in regard to this also.
@zeal I didn't say that, A Guest did :) Anyway, when f is a function name, &f gives you a function pointer. When f is already a function pointer, &f gives you a pointer to function pointer and that can't be used in a function call.
@ruslo: He's got a bit of a point: if you use the name of a function in a non-call context (i.e. as function_name, not function_name(args)), then it generally refers to the function address. But indeed: sizeof(function_name) is illegal and sizeof(&function_name) is OK, so there is a definite difference.
@jrok sorry for eerily referring to you but anyway thanks for clearing the doubt. Well if you read this please answer my other question which is related to once again pointer. As you may say this is already answered but i revised the question and please clear my doubt w.r.t to same.
2

It's c++ standard.

float Plus(float a, float b);
void Function_Pointer_func(float a, float b, float (*pt2Func)(float, float));

Function_Pointer_func(2, 5, Plus); // (1)
...
float result = pt2Func(a, b); // (2)

(1) is conversion of function to pointer (standard 2003, 4.3):

An lvalue of function type T can be converted to an rvalue of
type “pointer to T.” The result is a pointer to the function

(2) is function call (standard 2003, 5.2.2):

For an ordinary function call, the postfix expression shall be either
an lvalue that refers to a function (in which case the function-to-pointer
standard conversion (4.3) is suppressed on the postfix expression), or it
shall have pointer to function type.

[UPDATE] In detail:

void Replace() { 
   Function_Pointer_func(2, 5, Plus);
   Function_Pointer_func(2, 5, &Minus);
}

Minus is function => &Minus is pointer to function, so no conversion, 3-rd argument of Function_Pointer_func fit perfectly. Plus is a function, so to fit Function_Pointer_func it must be converted to pointer. Standard (1) says that it can be done automatically.

Call cases:

void Function_Pointer_func(float a, float b, float (*pt2Func)(float, float)) {
   float result = pt2Func(a, b); // call by pointer, see (2)
   float result = (*pt2Func)(a, b); // convert pointer to function, so 'normal' call
   float result = (&pt2Func)(a, b); // pointer to function pointer, nope, will not work
}

1 Comment

i don't understand your answer, please spare some time to explain or give some reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.