可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a weird typedef statement in a C++ program, generated by Py++.
double radius(int); // function to be wrapped
typedef double (*radius_function_type)(int);
bp::def("radius", radius_function_type(&radius)); // bp::def is a function for wrapping
What I figured out so far is that the above typedef statemnt is not of the type, most of us are familiar with,
typedef complex_type simple_alias;
Rather it is a way to declare pointer to a function which takes int as argument and returns double (same as the prototype). So my question now is that, how come pointer to a function (without dereferencing) be called with address of a function as an argument? This also doesn't match with the prototype. Somebody please explain!
回答1:
Your question is confusing. Are you asking what this does:
radius_function_type(&radius)"
This is just a C++ typecast, a bit like:
radius (int (42));
but since radius is already of type radius_function_type then you can just as easily do:
bp::def("radius", radius);
but as this is code generated by Py++, it's probably being extra careful with the output.
回答2:
It doesn't declare a function pointer variable but a function pointer typedef called radius_function_type
. radius_function_type(&radius)
is just a (redundant) cast for the function pointer itself. (The unary &
address-of operator is also redundant; for a function, radius
and &radius
are the same thing.)
On a low level, calling a function is just placing the arguments somewhere according to the underlying calling convention (usually on the stack) and then jumping to a memory address. So the compiler can call a function with just a pointer if it knows the function pointer type (function signature) and the pointer value itself.
回答3:
Well ... It is a bit similar to how arrays are related to pointers, in C and C++. The name of a function is basically a pointer, too. Seen from that perspective, it's not too surprising that given a definition:
int foo(int a, int b)
{
return a + b;
}
You can do the call either directly, through the pointer that is the function's name:
foo(1, 2);
or by storing that value in a separate variable, which must be declared as a pointer:
int (*pointer)(int, int) = foo;
pointer(1, 2);
In this case, we can call through the pointer variable directly, and there's also no need to explicitly "take the address of" the function by writing &foo
.
回答4:
Dereferencing (in way you think) a function's pointer means: accessing a CODE memory as it would be a DATA memory.
Function pointer isn't suppose to be dereferenced in that way. Instead, it is called.
I would use a name "dereference" side by side with "call". It's OK.
Anyway: C is designed in such a way that both function name identifier as well as variable holding function's pointer mean the same: address to CODE memory. And it allows to jump to that memory by using call () syntax either on an identifier or variable.
回答5:
Function pointer is basically the address of the function that needs to be invoked. To call the function pointed to by a function pointer, you consider the function pointer as though it were the name of the function that you wish to call. The act of calling it itself performs the dereference; there is no need for explicit dereference.
Function pointer syntax can look like pointers (with & and *) or that can be omitted as well. As @unwind already pointed out it is similar to how arrays are treated where bare array is similar to pointer and optionally you can prefix the array with & to get the address.