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?
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/
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.
The Clockwise Spiral Rule helps me understand things like this. From the site:
Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:
Keep doing this in a spiral/clockwise direction until all tokens have been covered.
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...
It's a pointer to a function taking the arguments 'LPUNKNOWN pUnk, HRESULT* phr' and it returns a pointer to a CUnknown.
it's a function pointer with two arguments that returns a CUnknown*
I think this is pointer to a function taking LPUNKNOWN and pointer to HRESULT, returning pointer to CUnknown
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;
Related
Normally, when declaring some variable, you put its type before it, like:
int a;
a function pointer may have type like: int(*)(int,int), in case we point to a function that takes two integers and returns an integer. But, when declaring such a pointer, its identifier is not after the type, like:
int(*)(int,int) mypointer;
instead, you must write the identifier in the middle:
int(*mypointer)(int,int);
why is this so?
I explain this in my answer to Why was the C syntax for arrays, pointers, and functions designed this way?, and it basically comes down to:
the language authors preferred to make the syntax variable-centric rather than type-centric. That is, they wanted a programmer to look at the declaration and think "if I write the expression *func(arg), that'll result in an int; if I write *arg[N] I'll have a float" rather than "func must be a pointer to a function taking this and returning that".
The C entry on Wikipedia claims that:
Ritchie's idea was to declare identifiers in contexts resembling their use: "declaration reflects use".
...citing p122 of K&R2.
This structure reflects how a normal function is declared (and used).
Consider a normal function definition:
int foo (int bar, int baz, int quux);
Now consider defining a function pointer to a function of the same signature:
int (*foo) (int, int, int);
Notice how the two structures mirror each other? That makes *foo much easier to identify as a function pointer rather than as something else.
If you're dealing with a function (not a pointer to one), the name is in the middle too. It goes like: return-type function-name "(" argument-list ")" .... For example, in int foo(int), int is the return type, foo the name and int the argument list.
A pointer to a function works pretty much the same way -- return type, then name, then argument list. In this case, we have to add a * to make it a pointer, and (since the * for a pointer is prefix) a pair of parentheses to bind the * to the name instead of the return type. For example, int *foo(int) would mean a function named foo that takes an int parameter and returns a pointer to an int. To get the * bound to foo instead, we need parentheses, giving int (*foo)(int).
This gets particularly ugly when you need an array of pointers to functions. In such a case, most people find it easiest to use a typedef for the pointer type, then create an array of that type:
typedef int (*fptr)(int);
fptr array[10];
I had seen at some places function pointers declared as
int (*foo) (int a, int b);
and at some places a and b are not mentioned and both still works.
so
int (*foo) (int, int)
is also correct.
A very simple way that I found to remember is as mentioned below:
Suppose function is declared as:
int function (int a , int b);
Step1: Simply put function in parentheses:
int (function) (int a , int b);
Step2: Place a * in front of function name and change the name:
int (*funcPntr) (int a , int b);
PS: I am not following proper coding guidelines for naming convention etc. in this answer.
There's the well known spiral and right-left rules etc. for reading complicated C++ types such as
int (*(*foo)(char *,double))[9][20];
Foo is a pointer (change direction, move out of parentheses)
to a function taking a pointer to char and a double, and returning (change direction again)
a pointer to (parentheses again, change direction)
a 2d-array of dimensions 9,20 of (reached right end, spiral outside to the left)
integers.
But how do I deal with types like this if there is no identifier, such as when defining a function parameter's type:
void foo(int *(*(* )(int(* )(int (* )(int))))())
^ ^ ^
identifiers omitted
How do I identify the innermost element in an intuitive way?
By the way, even the cdecl tool gives a syntax error on this last example, but it does compile.
Surely, the compiler has a well-defined way of parsing gibberish like this. How does it know where to start?
The rules for reading complex types assume that the type has already been parsed (and you know where the "innermost" point is). The rules for parsing work from the outside in, the same as reading complex expressions in math class. When you hit parentheses, give it a name and come back to it (unless it's simple enough to handle on its own). Disclaimer: I used a text editor to locate matching parentheses. ;)
The other consideration that comes into play with this declaration is that once a type is a function, the mess in the parameter list is a separate parse. For example, when parsing void (*)(big old mess), you have a pointer to a function. The big old mess is needed for the function's signature but not for understanding that you are dealing with a function.
Moving on to the example at hand:
void foo(int *(*(* )(int(* )(int (* )(int))))())
After reading void and foo, you hit parentheses with a complex mess inside. Give that mess a name.
void foo( A )
where A is int *(*(* )(int(* )(int (* )(int))))(). So your outermost parse is a unary function returning void, and we still need to parse the parameter, A. Note that we already know what the overall purpose of this text is: it declares a function named foo. The remaining types have no name because names for parameters are optional.
A: int *( B )()
where B is *(* )(int(* )(int (* )(int))). So the parameter to foo is something whose outermost type is a nullary function that returns a pointer to int. Presumably we will discover that the "something" is a pointer, but we still need to parse B to confirm that. (OK, skip ahead a little and see that B starts with an asterisk. It's a pointer to this nullary function.)
B: *(* )( C )
where C is int(* )(int (* )(int)). This is a pointer to a unary function whose parameter is some complex type, and whose return value is a pointer to what we parsed previously (the nullary function). As with the initial parse, we have discovered another place to start reading, as the mess has been pushed into the parameter list. The parameter to foo is a pointer to a unary function whose parameter is some complex type, and whose return value is a pointer to a nullary function that returns a pointer to int.
C: int(* )( D )
where D is int (* )(int). Again, the mess has moved into the parameter list. The thing at this level is a pointer to a unary function that returns an int.
D: int (* )(int)
Finally, simplicity: a pointer to a unary function that takes an int and returns an int.
So....
This declares foo to be a unary function returning void whose parameter is a pointer to a unary function, returning a pointer to a nullary function returning a pointer to int, whose parameter is a pointer to a unary function returning int whose parameter is a pointer to a unary function returning int whose parameter is int.
The English version is about as comprehensible as the code, no? :) Let's try something more structured.
foo
Returns: void
Parameter: pointer to a function
Returns: pointer to a function
Returns: pointer to int
Parameter: pointer to a function
Returns: int
Parameter: pointer to a function
Returns: int
Parameter: int
Whew. Don't do this at home, kids. Give your intermediate types names and save the programmers some grief.
So in "the c++ programming language, 4th edition", there's a paragraph I don't understand about conversion of pointer-to-function types. Here is some of the code sample.
using P1 = int(*)(int*);
using P2 = void(*)(void);
void f(P1 pf) {
P2 pf2 = reinterpret_cast<P2>(pf);
pf2(); // likely serious problem
// other codes
}
When I run this it crashed.
I'm not sure if I am right, but I initially think the "likely serious problem" comment is when pf got casted to P2 in pf2, I think pf2 is not pointing to anything? Because when I created a function that matches P2's type and point pf2 to it, it didn't crash and runs normally.
After the code, I read this:
We need the nastiest of casts, reinterpret_cast, to do conversion of pointer-to-function types. The reason is that the result of using a pointer to function of the wrong type is so unpredictable and system-dependent. For example, in the example above, the called function may write to the object pointed to by its argument, but the call pf2() didn’t supply any argument!
Now I'm completely lost starting from "For example, in the example above" part:
"may write to the object pointed to by its argument" //what object is it exactly?
"but the call pf2() didn’t supply any argument!" //"using P2 = void(*)(void);" doesn't really need an arguement does it?
I think I'm missing something here. Can someone explain this?
For example, in the example above, the called function may write to the object pointed to by its argument (...)
pf is a pointer to a function like this:
int foo(int* intPtr)
{
// ...
}
So it could be implemented to write to its argument:
int foo(int* intPtr)
{
*intPtr = 42; // writing to the address given as argument
return 0;
}
(...) but the call pf2() didn’t supply any argument!
When you call foo through its cast to type P2, it will be called without arguments, so it is unclear what intPtr will be:
P2 pf2 = reinterpret_cast<P2>(pf);
pf2(); // no argument given here, although pf2 really is foo() and expects one!
Writing to it will most likely corrupt something.
Moreover, compilers usually implement calls to functions that return something by reserving space for the return value first, that will then be filled by the function call. When you call a P1 using the signature of P2, the call to P2 won't reserve space (as the return value is void) and the actual call will write an int somewhere it should not, which is another source for corruption.
Now I'm completely lost starting from "For example, in the example
above" part:
"may write to the object pointed to by its argument" //what object is
it exactly?
P1 is a function expecting a non-const pointer-to-int argument. That means it very well may write to the int referenced in its argument.
"but the call pf2() didn’t supply any argument!" //"using P2 =
void(*)(void);" doesn't really need an arguement does it?
When you call the function through another function pointer type passing no argument, the expectations of the called function aren't met. It may try to interpret whatever is on the stack as an int pointer and write to it, causing undefined behavior.
This does fail, but not necessarily in the way one might expect.
The implementation of a function pointer is left up to the compiler (undefined). Even the size of a function pointer can be bigger than a void*.
What is guaranteed about the size of a function pointer?
There is no guarentees about anything in the value of the function pointer. In fact, the only even guarentee that the comparison operators will work between function pointers of the same type.
Comparing function pointers
The standard does provide that function pointers can store the values of other function types.
Casting the function pointer to another type undefined behavior, meaning the compiler can do whatever it wants. Whether or not you supply the argument really doesn't matter, and how that would fail depends on the calling convention of the system. As far as your concerned, it could allow "demons to fly out of your nose".
Casting a function pointer to another type
So that brings us back to the statement by the author:
We need the nastiest of casts, reinterpret_cast, to do conversion of pointer-to-function types. The reason is that the result of using a pointer to function of the wrong type is so unpredictable and system-dependent. For example, in the example above, the called function may write to the object pointed to by its argument, but the call pf2() didn’t supply any argument!
That is trying to make the point that with no argument specified, if the function writes the output, it will write to some uninitialized state. Basically, if you look at the function as
int foo(int* arg) {*arg=10;}
if you didn't initialize arg, the author says you could be writing anywhere. But again, there is no guarentee that this even matters. The system could store functions with the footprint int (*)(int*) and void(*)(void) in completely different memory space, in which case instead of the above problem you'd have a jump into a random location in the program. Undefined behavior is just that: undefined.
Just don't do it man.
The outcome of the following macro is clear:
#define CRASH() do {\
*(int *)(uintptr_t)0xbbadbeef = 0;\
((void(*)())0)();\
} while (false)
My question is, what does the line
((void(*)())0)();
break down to, in English? For example, "this is a function that returns a pointer to a...."
It looks like it casts 0 as a function pointer (with the signature that it takes not parameters and has void return type) and then invokes it.
( ( void(*)() ) 0 ) ();
/* cast..*/ /* fn pointer signature */ /*..cast 0 */ /* invocation */
Which is another way to say that it's trying to invoke (call) a function that's expected to be located in memory at address 0x00000000 - which is guaranteed to be an invalid address.
Cast 0 to a pointer to a void function that takes can be called with no parameters (the (void(*)())0 part of the expression)
Call that function through a pointer with an empty parameter list (the () part after it).
EDIT 1: Edited in response to Cristoph's comment.
It casts a NULL pointer to a method taking no parameters and returning void, and attempts to call this method.
Needless to say, it crashes, so the name CRASH suits it very well.
It casts 0 to a function pointer, where the function takes no argument and returns void, then tries to call this function. It basically dereferences a null pointer.
It casts 0 to a pointer to a function, then attempts to call that function. Which will cause a segfault and crash.
Edit: way too much competition for these questions. Upvotes all round, and I'm going to bed :)
It means “treating NULL pointer as pointer to void function(), call function()”.
It takes the value zero, and casts it to a function pointer that doesn't return anything (void).
Presumably, the purpose is that when you call this "function", it calls address zero, which should indeed crash the application.
For me it is simpler to translate to a different C++, rather than directly to english:
typedef void (void_func_t)(); // type of a function taking no arguments
// and returning void
typedef void_fnct_t* void_func_ptr; // pointer to such a function
static_cast<void_func_ptr>(0)(); // call that function
// ((void_func_ptr)0)(); // pure C equivalent cast
if fp is a pointer to a function, *fp is the function itself, so(fp)()is the way to invoke it. ANSI C permits this to be abbreviated as fp(), bu keep in mind that it is only an abbreviation. -------C traps an pitfalls.
( ( void()() )0 ) () is the avvreviation of ( ( void()() )0 )()
Is this correct?
int (*(*ptr)())[];
I know this is trivial, but I was looking at an old test about these kind of constructs, and this particular combination wasn't on the test and it's really driving me crazy; I just have to make sure. Is there a clear and solid understandable rule to these kind of declarations?
(ie: pointer to... array of.. pointers to... functions that.... etc etc)
Thanks!
R
The right-left rule makes it easy.
int (*(*ptr)())[];can be interpreted as
Start from the variable name ------------------------------- ptr
Nothing to right but ) so go left to find * -------------- is a pointer
Jump out of parentheses and encounter () ----------- to a function that takes no arguments(in case of C unspecified number of arguments)
Go left, find * ------------------------------------------------ and returns a pointer
Jump put of parentheses, go right and hit [] ---------- to an array of
Go left again, find int ------------------------------------- ints.
In almost all situations where you want to return a pointer to an array the simplest thing to do is to return a pointer to the first element of the array. This pointer can be used in the same contexts as an array name an provides no more or less indirection than returning a pointer of type "pointer to array", indeed it will hold the same pointer value.
If you follow this you want a pointer to a function returning a pointer to an int. You can build this up (construction of declarations is easier than parsing).
Pointer to int:
int *A;
Function returning pointer to int:
int *fn();
pointer to function returning a pointer to int:
int *(*pfn)();
If you really want to return a pointer to a function returning a pointer to an array of int you can follow the same process.
Array of int:
int A[];
Pointer to array of int:
int (*p)[];
Function returning pointer ... :
int (*fn())[];
Pointer to fn ... :
int (*(*pfn)())[];
which is what you have.
You don't. Just split it up into two typedefs: one for pointer to int array, and one for pointer to functions. Something like:
typedef int (*IntArrayPtr_t)[];
typedef IntArrayPtr_t (*GetIntArrayFuncPtr_t)(void);
This is not only more readable, it also makes it easier to declare/define the functions that you are going to assign the variable:
IntArrayPtr_t GetColumnSums(void)
{ .... }
Of course this assumes this was a real-world situation, and not an interview question or homework. I would still argue this is a better solution for those cases, but that's only me. :)
If you feel like cheating:
typedef int(*PtrToArray)[5];
PtrToArray function();
int i = function;
Compiling that on gcc yields: invalid conversion from 'int (*(*)())[5]' to 'int'. The first bit is the type you're looking for.
Of course, once you have your PtrToArray typedef, the whole exercise becomes rather more trivial, but sometimes this comes in handy if you already have the function name and you just need to stick it somewhere. And, for whatever reason, you can't rely on template trickery to hide the gory details from you.
If your compiler supports it, you can also do this:
typedef int(*PtrToArray)[5];
PtrToArray function();
template<typename T> void print(T) {
cout << __PRETTY_FUNCTION__ << endl;
}
print(function);
Which, on my computer box, produces void function(T) [with T = int (* (*)())[5]]
Being able to read the types is pretty useful, since understanding compiler errors is often dependent on your ability to figure out what all those parenthesis mean. But making them yourself is less useful, IMO.
Here's my solution...
int** (*func)();
Functor returning an array of int*'s. It isn't as complicated as your solution.
Using cdecl you get the following
cdecl> declare a as pointer to function returning pointer to array of int;
Warning: Unsupported in C -- 'Pointer to array of unspecified dimension'
(maybe you mean "pointer to object")
int (*(*a)())[]
This question from C-faq is similar but provides 3 approaches to solve the problem.