0

Today I have learned that function pointers and data pointers are not the same and are therefore not compatible with each other (Why are function pointers and data pointers incompatible in C/C++?). My question however is, are different function (non member) pointers compatible with each other (are implemented the same way).

In code:

typedef void(*FuncPtr0)();
typedef void(*FuncPtr1)(int);

FuncPtr0 p0;
FuncPtr1 p1;

p0 = reinterpret_cast<FuncPtr0>(p1);    // will this always work, if p1 really 
p0();                                   // points to a function of type FuncPtr0

Thanks for your help!

Community
  • 1
  • 1
rozina
  • 4,120
  • 27
  • 49

2 Answers2

9

n3376 5.2.10/6

A function pointer can be explicitly converted to a function pointer of a different type. The effect of calling a function through a pointer to a function type (8.3.5) that is not the same as the type used in the definition of the function is undefined. Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Thank you very much! It seems it was quite easy to find the answer to this question. May I ask you, how did you go about finding the citation in the standard? – rozina Nov 26 '13 at 08:15
  • @rozina simply look on paragraph, that talk about reinterpret_cast. – ForEveR Nov 26 '13 at 08:30
  • I googled and found out that the standard is not free, which explains why no google search result ever shows the standard only quotes here on stackoverflow :) Thanks again though! – rozina Nov 26 '13 at 08:54
  • @rozina google about standard drafts. They are free. My quote is from n3376 draft. – ForEveR Nov 26 '13 at 08:59
1

No they are not compatible and will invoke undefined behavior. You will have unspecified results.

In fact you can cast them to each other, but you shouldn't call a function pointer which points to a non-compatible function signature. For example, see this code :

typedef void(*FuncPtr0)();

void p1f()      { std::cout << "ONE";        }
void p2f(int x) { std::cout << "TWO " << x ; }

int main()
{
    FuncPtr0 p0 = reinterpret_cast<FuncPtr0>(p2f);
    p0();
} 

Output

TWO 1

The question is who set argument x to 1 ? It may run but the result is unspecified. In my system the result is something else (garbage) TWO 39.

masoud
  • 55,379
  • 16
  • 141
  • 208