First off, this is quite ugly C-style code.
typedef void*(*AnimalCreation)();
To interpret this, follow the general rule of C & C++ declaration reading: if you type the declaration as an expression, you'll get its type.
*AnimalCreation
This means AnimalCreation
is a pointer
(*AnimalCreation)()
This means *AnimalCreation
is a function taking no arguments, so AnimalCreation
is a pointer to function taking no arguments
void *(*AnimalCreation)()
This means (*AnimalCreation)()
is a void*
(= pointer to void
), so AnimalCreation
is a pointer to a function which takes no arguments and returns a void*
.
If it was just typedef void (*AnimalCreation)();
, it would be a pointer to a function taking no arguments and returning no value (i.e. returning void
).
Now, foo()
.
That takes a void*
(pointer to anything) and interprets it as AnimalCreation
- as a pointer to function taking no arguments and returning a void*
. If the argument passed to foo
was actually of that type, all is well. If something else is passed in, the program will exhibit Undefined Behaviour, which means anything can happen. It would most likely crash, as it could be trying to interpret data as code, for example.
foo()
calls that function passed in, which returns a void*
. foo()
then interprets that as a pointer to Animal
. If that's what the function actually returned, great. If not, Undefined Behaviour again.
Finally, the call you're showing will force the Undefined Behaviour to happen, because it's passing in the address of a pointer to an object. But, as stated above, foo()
will interpret that as the address of a function, and try to call that function. Hilarity ensues.
To summarize, such code is bad and its author should feel bad. The only place you'd expect to see such code is interoperability with a C-style external library, and in such case it should be extremely well documented.