23

I couldn't find an answer to this anywhere. I just read K&R and saw them calling a function pointer like this:

(*ptr)(arg1, arg2);

I vividly remember, however, to have seen someone using them like this:

ptr(arg1, arg2);

That might have been in C++, though.

  • How are the rules?
  • Do they differ in C and C++?
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
user3692301
  • 233
  • 1
  • 4

2 Answers2

16

TL;DR

The rules in C and C++ are the same, there's no difference between the two.


What does the C++ Standard (n3797) say?

5.2.2p1 Function call [expr.call]

A function call is a postfix expression followed by parentheses containing a possible empty, comma-separated list of initializer-clauses which constitute the arguments to the function.

The postfix expression shall have function type or pointer to function type.


What does the C standard (n1570) say?

6.3.2.1p4 Lvalues, arrays, and function designators

A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".

6.5.2.2p1 Function calls

The expression that denotes the called function shall have type pointer to function returning void or returning a complete object type other than an array type.



Conclusion?

How the rule are expressed differs between C++ and C. In C the implicit function-to-pointer conversion always applies when calling a function, whereas C++ states that the "postfix expression" could be either a pointer, or a variable of function type.

However; your question is if the two ways of calling a function through a pointer differs between C++ and C, and the answer is: No, there's no difference between (1), (2), and (3), nor is there a difference between the two languages.

(*fptr)(123);   // (1)

fptr(123);      // (2)

(***fptr)(123); // (3)

Note: Be aware that the there's no difference between (*fptr) (...) and fptr (...) when it comes to calling a function, but that they can be vastly different in other contexts.

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
4

How are the rules? Do they differ in C and C++?

No. Dereferencing the function pointer in this context was never necessary, as it is redundant.

However, you might still want to use the asterisk-notation to underline that you are calling a function through a function pointer. That may also be the reason for the author of the snippet in your post.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • 1
    Interesting that K&R do it then. Does anyone have any idea why? @LightnessRacesinOrbit: What kind of benefit do you get from knowing the intent in this context? – user3692301 May 30 '14 at 17:48
  • @LightnessRacesinOrbit Yes, but the question is clearly not about the intent. Edited the post though. – Columbo May 30 '14 at 17:49
  • 1
    @Arcoth This question may not be, but programming is. – Lightness Races in Orbit May 30 '14 at 18:22
  • 2
    What other intent could there be? – nobody May 30 '14 at 19:59
  • 1
    Maybe it was necessary in early versions of the language (e.g. early 1970s I mean) and they never changed their style. K&R2 still casts malloc despite this being a mistake ever since `void *` was added. – M.M May 30 '14 at 22:36
  • 1
    @LightnessRacesinOrbit I don't understand how my answer is actually saying the opposite, anyway. Clearly it is redundant, because both a function and a function pointer are function objects (acc. to standard). So what intent is there to clarify, really? That it is a function pointer you are using? Not convincing. – Columbo May 30 '14 at 22:50
  • 3
    @AndrewMedico A reader may not see that the thing being called is a variable. The `*` operator makes an indirect-branch call look different from a regular call, even if it's strictly also allowed for direct calls too. – Potatoswatter May 31 '14 at 06:17