Search code examples
c++syntaxfunction-pointersfunction-prototypes

Alternate function syntax/function prototypes?


For all the time I've been using function pointers in C++ I've been declaring them as void (*function)(void). This is how I originally saw it in a tutorial and how tutorials still teach it.

But today, I was reading wikipedia's article about higher order functions when I discovered an example using an alternate syntax in which the * and the brackets surrounding the function pointer's variable/type name were not present, as seen here.

I tested to see if the form void function(void) worked for variables, arguments and typedefs. It didn't work for variables but it worked for arguments and typedefs with no apparent change, practically interchangeable with the standard function pointer syntax.

I dug a bit further and found an SO question that seems to imply it's the syntax for a 'function prototype' rather than a function pointer. However wikipedia's explanation of function prototypes sounds a lot like just predeclaring functions.

I apologise for the wide scope of my question, but what exactly is this syntax?

  • Does it define a 'function prototype' or a function pointer?
  • If it's a function prototype, are function pointers and function prototypes the same or do they just behave the same?
  • If it's not a function prototype does that mean 'function prototypes' are just predeclarations of functions?
  • If this syntax is equivalent to the standard function pointer syntax, why is the more verbose (and arguably harder to read) syntax the more commonly taught form?
  • Do the syntaxes produce different results/have different meanings and I somehow haven't noticed?

Solution

  • No, they're not the same. Anymore than arrays and pointers are not the same just because you can write int A[] as a parameter. The specific rule can be found in the draft standard n4567:

    §8.3.5/5 ... After determining the type of each parameter, any parameter of type "array of T" or of function type T is adjusted to be "pointer to T". ...

    It is more explicit later on:

    §13.2/3 ...

    • Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type (8.3.5). [ Example:

       void h(int());
       void h(int (*)());     // redeclaration of h(int())
       void h(int x()) { }    // definition of h(int())
       void h(int (*x)()) { } // ill-formed: redefinition of h(int())
      

      end example ] ...

    The rule applies in other places as well (not a complete list):

    • non-type template parameters
    • template argument deduction
    • exception handlers