tags:

views:

110

answers:

7
CUnknown* (*)( LPUNKNOWN pUnk, HRESULT* phr );

Seems I've always been in trouble reading such complicated pointers..

How do you read it? what if the expression even longer?

A: 

It's a pointer to a function taking the arguments 'LPUNKNOWN pUnk, HRESULT* phr' and it returns a pointer to a CUnknown.

Frerich Raabe
A: 

it's a function pointer with two arguments that returns a CUnknown*

Sanjay Manohar
**How** did u read it?
Alan
A: 

I think this is pointer to a function taking LPUNKNOWN and pointer to HRESULT, returning pointer to CUnknown

killer_PL
+3  A: 

Everyone has said what it is, but you asked how to read it.

Function pointer syntax is as follows:

RETURN_VALUE (*POINTER_NAME) (ARGUMENT LIST)

So

foo (*bar) (baz)

is a pointer to a function taking baz and returning foo, and the pointer is called bar.

In the case that you only want to write the type of a function pointer, rather than declare one, you just leave out the name, e.g.

RETURN_VALUE (*) (ARGUMENT_LIST)

as you see here.

For parsing hard-to-understand C declarations, there's a nice program called cdecl available on most Linux and Unix-like systems, as well as available as a web app: http://cdecl.org/

Tyler McHenry
What if it's `CUnknown* (***)( LPUNKNOWN pUnk, HRESULT* phr );` ? is that valid any more?
Alan
@Alan: `***` is valid. It declares pointer to pointer to pointer to function.
J.F. Sebastian
cdecl.org gives error syntax as result both for your question and for your original statement.
Adriano Varoli Piazza
Yes, that's a pointer-to-pointer-to-pointer-to-function with the given arguments and return value, much like `int***` is a pointer-to-pointer-to-pointer-to-int.
Tyler McHenry
@Alan: http://cdecl.ridiculousfish.com/?q=double%2A+%28%2A%2A%2Af%29%28+char%2A+%2C+int%2A+%29%3B
J.F. Sebastian
@Adriano It's because really you're not supposed to give *names* to the parameters in a function pointer declaration, just types. I'm not not sure if the C standard *forbids* giving names, but cdecl doesn't like it.
Tyler McHenry
@Tyler: I'm not blaming you, but would be helpful to have some kind of help in the site. * (***)( int, * ); fails too, and other combos do too.
Adriano Varoli Piazza
I see that it only seems to accept standard types. An accepted decl is `int* (***f)( char* , int* )`
Adriano Varoli Piazza
A: 

For some function:

int f(int a, int& b, int* c);

The type of the expression:

&f

Or, equivalently:

f

Is:

int(*)(int, int&, int*)

And an easy way to remember this is that a function pointer type specifier is just like a function declaration, except with the name replaced with (*). You can also perform a typedef:

typedef int(*ftype)(int, int&, int*);

And now you can write:

ftype func = f;

Rather than:

int(*func)(int, int&, int*) = f;
Jon Purdy
+3  A: 

What I learned from books and Uni was to start at the middle and proceed outwards back and forth. The trick is only to do it slowly, and know where the middle actually is.

You have a

CUnknown* (*)( LPUNKNOWN pUnk, HRESULT* phr );

that's a pointer (*)

Now we go right: it's a pointer to a function because the next thing is a (

The arguments of the function are a LPUNKNOWN and a pointer to HRESULT, and that's it.

Now we go left: the function returns a pointer to CUnknown.

So, as stated by everyone, it's a pointer to a function that takes two arguments -a LPUNKNOWN and a pointer to a HRESULT- and returns a pointer to CUnknown.

Link beauties: this and this.

Adriano Varoli Piazza
+1  A: 

The Clockwise Spiral Rule helps me understand things like this. From the site:

  1. Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:
  2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.

  3. Always resolve anything in parenthesis first!

    [X] or []

=> Array X size of... or Array undefined size of...

(type1, type2)

=> function passing type1 and type2 returning...

*

=> pointer(s) to...

Jergason