3

Everytime I look at a C function pointer, my eyes glaze over. I can't read them.

From here, here are 2 examples of function pointer TYPEDEFS:

typedef int (*AddFunc)(int,int);
typedef void (*FunctionFunc)();

Now I'm used to something like:

typedef vector<int> VectorOfInts ;

Which I read as

typedef vector<int> /* as */ VectorOfInts ;

But I can't read the above 2 typedefs. The bracketing and the asterisk placement, it's just not logical.

Why is the * beside the word AddFunc..?

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 2
    There is a nice explanation for reading function-pointer types at the end of this answer: http://stackoverflow.com/questions/2250397/interpretation-of-int-a3/2250448#2250448 – Georg Fritzsche May 02 '10 at 19:09
  • 1
    If you don't care about getting a language lawyer, you can just use `identity`. Like `typedef identity::type *AddFuncPtr;` – Johannes Schaub - litb May 02 '10 at 19:19
  • 1
    @Johannes: Great idea, it "just" leaves `identity<>` to be standardized and implemented by every vendor. And it's not exactly that much of an improvement over C's declaration syntax... – sbi May 02 '10 at 19:30
  • @sbi: But then it gets you as close to `typedef FnType* FnPtrType` as it gets with C++ declarations. – Georg Fritzsche May 02 '10 at 19:34
  • 2
    And in C++0x you can do `typedef alias *AddFuncPtr;` with template aliases. – Johannes Schaub - litb May 02 '10 at 19:36
  • @gf: I understand that this gets you as close to what other typedefs look. But it's still far from being ideal, and that's whyt I was complaining about. @Johannes: Nice to see this implemented in C++11. – sbi May 02 '10 at 19:51

5 Answers5

5

When you're comprehending it, just ignore the typedef, the parentheses around the function name, and the asterisk in front of the name. Then you have int AddFunc(int,int);.

The point of the parentheses in (*functionName) is to specifically group the * with the name of the typedef. The * is necessary to indicate that this is a function pointer.

So any function that takes two ints as arguments and returns an int complies to the AddFunc "interface", if you will. Likewise, any function accepting no arguments are returning void can be used for a FunctionFunc.

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
4

The actual type of the first one is

int (*)(int,int);

(that is, a pointer to a function that takes two parameters of type int and returns an int)

The * identifies it as a function pointer. AddFunc is the name of the typedef.

cdecl can help with identifying particularly complex type or variable declarations.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 2
    This is the weirdest thing ever! So if we have `float (*GetPtr1(const char opCode))(float, float)`, that is a function named `GetPtr1` who returns `float(*) (float,float)`. I find the second easier to read, why doesn't the syntax go `float(*)(float,float) GetPtr1(const char opCode);`? That would be [hella](http://www.youtube.com/watch?v=QtTj4cramPM) easier to read imo! – bobobobo Aug 23 '10 at 21:38
3

I read typedef vector<int> /* as */ VectorOfInts ;

It's probably better if you see a typedef as an object definition with a typedef put in front:

  • int i; defines an integer object
    typedef int t; defines an integer type.

  • vector<int> v; defines a vector object
    typedef vector<int> v; defines a vector type.

  • int (*AddFunc)(int,int) defines a function pointer
    typedef int (*AddFunc)(int,int) defines a function pointer type.

C's declaration syntax, inherited by C++, is a mess. I agree that typedef int (*)(int,int) AddFunc; would make more sense. But C's declaration syntax is 40 years old, has never changed, and never will. You'd better get used to it.

sbi
  • 219,715
  • 46
  • 258
  • 445
2

Function declarations look like this:

int AddFunc(int,int);
void FunctionFunc();

A typedef defining a function type looks the same, just with typedef in front:

typedef int AddFunc_t(int,int);
typedef void FunctionFunc_t();

To define a pointer to such a function type, there needs to be an additional * with additional parenthesis to specify where that * belongs to:

typedef int (*pAddFunc_t)(int,int);
typedef void (*pFunctionFunc_t)();

(The * is always right before the typename/variable that gets defined as a pointer.)

To read such a function pointer proceed in the opposite direction: leave out the (* ... ) around the type name and the typedef in front. The result then looks like a normal function declaration of the relevant type.

sth
  • 222,467
  • 53
  • 283
  • 367
0

The asterisk indicates that it's a function POINTER :)

mingos
  • 23,778
  • 12
  • 70
  • 107