Abstracting function parameter format and its effects on performance? - c++

I am developing a VM and I would like to make it possible to call compiled functions. However, because every function may end up having a different signature, my plan is to generalize all calls to 2 possible scenarios - a call for function with no return and no parameters, and a call to a function which takes one void * parameter.
The plan is to use it similarly to thiscall - all parameters are properly aligned at the location of the passed pointer and parameters are retrieved through indirection. Shouldn't be slower than reading them from the stack, at least IMO.
So instead of:
int foo(int a, int b) { return a+b; }
I can have something like:
void foo2(void *p) {
*(int*)p = *(int*)(p + 4) + *(int*)(p + 8);
}
So my question is what could potentially go wrong using this approach? What I can tell right away is it works "in the dark" so it would be crucial to calculate the offsets correctly. It is also a little inconvenient since all the temporaries need to be provided by the user. Assuming my VM compiler will deal with those two issues, I am mostly concerned about performance - I don't want to create a normal function and for each normal function a void * wrapper - I would like to directly use that convention for all functions, so I can't help but wonder how good of a job will the compiler do of inlining the functions when used in compiled code? Are there going to be any other possible performance implications I am overlooking (excluding __fastcall which will use one more register and one less indirection)?

Performance wise (and ease of use) you will probably be best off with cdecl - everything goes onto the stack. The C standard allows you to specify function prototypes with arbitrary arguments
typedef void (__cdecl * function_with_any_parameters)();
You will have to make sure to define all functions that you wish to invoke as:
void __cdecl f(type1 arg1, type2 arg2, type3 arg3); // any amount of arguments
And just invoke them with the right amount of arguments:
f(arg1, arg2, arg3, arg4);
If you wish to go through a single pointer then you do have extra overhead: the one pointer. The easiest way would be to define all functions as accepting a pointer to an anonymous struct:
void f(struct {type1 a; type2 b;} * args);
Then you can invoke the function with a pointer to the appropriate struct to avoid any misalignments.
struct {type1 a; type2 b;} args = {arg1, arg2};
f(&args);
You are effectively implementing cdecl on your own.

After running a few benchmarks I'd say the compiler does a pretty good job of optimizing similar pointer functions. The void * function is just as fast as the add function and the regular + operator.
It seems that this convention will be useful to provide the necessary calling abstraction without hurting optimizations and overall performance. The only sacrifice is safety, which may or may not be a primary concern depending on the application context.

Related

Passing pointer to struct, vs. passing void pointer and casting to struct

I'm working on a legacy code base that has this pattern:
struct sometype_t { /* ... */ };
int some_method(void *arg1) { // void pointer
((sometype_t*)arg1)->prop1; // cast
}
Is there any (common) scenario where it would be unsafe to use sometype_t * instead of void *?
int some_method(sometype_t *arg1) {
arg1->prop1;
}
The pointer isn't passed across ABIs or into 3rd-party libraries; it stays entirely within C++ code that we own.
It's usually not a good choice, but the only situation I'm aware of where this really make sense is if you want to have stateful callbacks passed into a function, without using templates:
void takes_callback(void(*f)(void*), void * data);
Basically the gist is that since you aren't using templates, you have to fix the function signature you accept (of course, it can and often does take other arguments and return something as well). If you just call the function with your own parameters though, the function can only hold state between calls via global variables. So instead the contract for takes_callback promises to call f with data as a parameter.
So, if you wanted to use some_method as a callback in such an API, you would have to have it take void*, and do the cast internally. Obviously, you are throwing away type safety here, and if you happen to call takes_callback with &somemethod and a pointer to anything that's not a sometype_t you have UB.
Having a C ABI is one reason to avoid templates, but it's not the only one. Maybe they were worried about code bloat, or wanted to keep the implementation in a .so so that versions could be upgraded without recompiling, etc.
The obvious common scenario that immediately comes to mind is callbacks for some functions from C standard library.
For example, the proper way to write the comparison callback for std::qsort is to declare the function with two const void * arguments and then cast them to proper specific pointer types inside the callback.
Replacing these const void * parameters with specifically-typed pointers will simply prevent the code from compiling.

What's the best way to wrap a C callback with a C++11 interface?

Let's say this is a C function to be wrapped:
void foo(int(__stdcall *callback)());
The two main pitfalls with C function pointer callbacks are:
Not being able to store bind expressions
Not being able to store capturing lambdas
I would like to know the best way to wrap functions like these to do so. The first is particularly useful for a member function callback, and the second for an inline definition that uses surrounding variables, but those are not the only uses.
The other property of these particular function pointers is that they need to use the __stdcall calling convention. This, to my knowledge, eliminates lambdas as an option completely, and is a bit of a nuisance otherwise. I'd like to allow at least __cdecl as well.
This is the best I am able to come up with without things starting to bend back to relying on support that function pointers don't have. It would typically be in a header. Here is the following example on Coliru.
#include <functional>
//C function in another header I have no control over
extern "C" void foo(int(__stdcall *callback)()) {
callback();
}
namespace detail {
std::function<int()> callback; //pretend extern and defined in cpp
//compatible with the API, but passes work to above variable
extern "C" int __stdcall proxyCallback() { //pretend defined in cpp
//possible additional processing
return callback();
}
}
template<typename F> //takes anything
void wrappedFoo(F f) {
detail::callback = f;
foo(detail::proxyCallback); //call C function with proxy
}
int main() {
wrappedFoo([&]() -> int {
return 5;
});
}
There is, however, a major flaw. This is not re-entrant. If the variable is reassigned to before it's used, the old function will never be called (not taking into account multithreading issues).
One thing I have tried that ended up doubling back on itself was storing the std::function as a data member and using objects, so each would operate on a different variable, but there was no way to pass the object to the proxy. Taking the object as a parameter would cause the signature to mismatch and binding it would not let the result be stored as a function pointer.
One idea I have, but have not played around with is a vector of std::function. However, I think the only real safe time to erase from it would be to clear it when nothing is using it. However, each entry is first added in wrappedFoo, then used in proxyCallback. I'm wondering if a counter that is incremented in the former and decremented in the latter, then checked for zero before clearing the vector would work, but it sounds like a more convoluted solution than necessary anyway.
Is there any way to wrap a C function with a function pointer callback such that the C++ wrapped version:
Allows any function object
Allows more than just the C callback's calling convention (if it's critical that it's the same, the user can pass in something with the right calling convention)
Is thread-safe/re-entrant
Note: The obvious solution, stated as part of Mikael Persson's answer, is to make use of the void * parameter that should exist. However, this is sadly not a be-all, end-all option, mostly due to incompetence. What possibilities exist for those functions that do not have this option is where this can get interesting, and is the primary route to a very useful answer.
You are, unfortunately, out of luck.
There are ways to generate code at runtime, for example you can read on LLVM trampoline intrinsics where you generate a forwarding function that stores additional state, very akin to lambdas but runtime defined.
Unfortunately none of those are standard, and thus you are stranded.
The simplest solution to pass state is... to actually pass state. Ah!
Well defined C callbacks will take two parameters:
A pointer to the callback function itself
A void*
The latter is unused by the code itself, and simply passed to the callback when it is called. Depending on the interface either the callback is responsible to destroy it, or the supplier, or even a 3rd "destroy" function could be passed.
With such an interface, you can effectively pass state in a thread-safe & re-entrant fashion at the C level, and thus naturally wrap this up in C++ with the same properties.
template <typename Result, typename... Args)
Result wrapper(void* state, Args... args) {
using FuncWrapper = std::function<Result(Args...)>;
FuncWrapper& w = *reinterpret_cast<FuncWrapper*>(state);
return w(args...);
}
template <typename Result, typename... Args)
auto make_wrapper(std::function<Result(Args...)>& func)
-> std::pair<Result (*)(Args...), void*>
{
void* state = reinterpret_cast<void*>(&func);
return std::make_pair(&wrapper<Result, Args...>, state);
}
If the C interface does not provide such facilities, you can hack around a bit, but ultimately you are very limited. As was said, a possible solution is to hold the state externally, using globals, and do your best to avoid contention.
A rough sketch is here:
// The FreeList, Store and Release functions are up to you,
// you can use locks, atomics, whatever...
template <size_t N, typename Result, typename... Args>
class Callbacks {
public:
using FunctionType = Result (*)(Args...);
using FuncWrapper = std::function<Result(Args...)>;
static std::pair<FunctionType, size_t> Generate(FuncWrapper&& func) {
// 1. Using the free-list, find the index in which to store "func"
size_t const index = Store(std::move(state));
// 2. Select the appropriate "Call" function and return it
assert(index < N);
return std::make_pair(Select<0, N-1>(index), index);
} // Generate
static void Release(size_t);
private:
static size_t FreeList[N];
static FuncWrapper State[N];
static size_t Store(FuncWrapper&& func);
template <size_t I, typename = typename std::enable_if<(I < N)>::type>
static Result Call(Args...&& args) {
return State[I](std::forward<Args>(args)...);
} // Call
template <size_t L, size_t H>
static FunctionType Select(size_t const index) {
static size_t const Middle = (L+H)/2;
if (L == H) { return Call<L>; }
return index <= Middle ? Select<L, Middle>(index)
: Select<Middle + 1, H>(index);
}
}; // class Callbacks
// Static initialization
template <size_t N, typename Result, typename... Args>
static size_t Callbacks<N, Result, Args...>::FreeList[N] = {};
template <size_t N, typename Result, typename... Args>
static Callbacks<N, Result, Args...>::FuncWrapper Callbacks<N, Result, Args...>::State[N] = {};
This problem has two challenges: one easy and one nearly impossible.
The first challenge is the static type transformation (mapping) from any callable "thing" to a simple function pointer. This problem is solved with a simple template, no big deal. This solves the calling convention problem (simply wrapping one kind of function with another). This is already solved by the std::function template (that's why it exists).
The main challenge is the encapsulation of a run-time state into a plain function pointer whose signature does not allow for a "user-data" void* pointer (as any half-decent C API would normally have). This problem is independent of language (C, C++03, C++11) and is nearly impossible to solve.
You have to understand a fundamental fact about any "native" language (and most others too). The code is fixed after compilation, and only the data changes at run-time. So, even a class member function that appears as if it's one function belonging to the object (run-time state), it's not, the code is fixed, only the identity of the object is changed (the this pointer).
Another fundamental fact is that all external states that a function can use must either be global or passed as a parameter. If you eliminate the latter, you only have global state to use. And by definition, if the function's operation depends on a global state, it cannot be re-entrant.
So, to be able to create a (sort-of-)re-entrant* function that is callable with just a plain function pointer and that encapsulate any general (state-ful) function object (bind'ed calls, lambdas, or whatever), you will need a unique piece of code (not data) for each call. In other words, you need to generate the code at run-time, and deliver a pointer to that code (the callback function-pointer) to the C function. That's where the "nearly impossible" comes from. This is not possible through any standard C++ mechanisms, I'm 100% sure of that, because if this was possible in C++, run-time reflection would also be possible (and it's not).
In theory, this could be easy. All you need is a piece of compiled "template" code (not template in the C++ sense) that you can copy, insert a pointer to your state (or function object) as a kind of hard-coded local variable, and then place that code into some dynamically allocated memory (with some reference counting or whatever to ensure it exists as long as it's needed). But making this happen is clearly very tricky and very much of a "hack". And to be honest, this is quite ahead of my skill level, so I wouldn't even be able to instruct you on how exactly you could go about doing this.
In practice, the realistic option is to not even try to do this. Your solution with the global (extern) variable that you use to pass the state (function object) is going in the right direction in terms of a compromise. You could have something like a pool of functions that each have their own global function object to call, and you keep track of which function is currently used as a callback, and allocate unused ones whenever needed. If you run out of that limited supply of functions, you'll have to throw an exception (or whatever error-reporting you prefer). This scheme would be essentially equivalent to the "in theory" solution above, but with a limited number of concurrent callbacks being used. There are other solutions in a similar vein, but that depends on the nature of the specific application.
I'm sorry that this answer is not giving you a great solution, but sometimes there just aren't any silver bullets.
Another option is to avoid using a C API that was designed by buffoons who never heard of the unavoidable and tremendously useful void* user_data parameter.
* "sort-of" re-entrant because it still refers to a "global" state, but it is re-entrant in the sense that different callbacks (that need different state) do not interfere with each other, as is your original problem.
As said before, a C function pointer does not contain any state, so a callback function called with no arguments can only access global state. Therefore, such a "stateless" callback function can be used only in one context, where the context is stored in a global variable. Then declare different callbacks for different contexts.
If the number of callbacks required changes dynamically (for example, in a GUI, where each windows opened by the user requires a new callback to handle input to that window), then pre-define a large pool of simple state-less callbacks, that map to a statefull callback. In C, that could be done as follows:
struct cbdata { void (*f)(void *); void *arg; } cb[10000];
void cb0000(void) { (*cb[0].f)(cb[0].arg); }
void cb0001(void) { (*cb[1].f)(cb[1].arg); }
...
void cb9999(void) { (*cb[9999].f)(cb[99999].arg); }
void (*cbfs[10000])(void) =
{ cb0000, cb0001, ... cb9999 };
Then use some higher level module to keep a list of available callbacks.
With GCC (but not with G++, so the following would need to be in a strictly C, not C++ file), you can create new callback functions even on the fly by using a not-so-well-known GCC feature, nested functions:
void makecallback(void *state, void (*cb)(void *), void (*cont)(void *, void (*)()))
{
void mycallback() { cb(state); }
cont(state, mycallback);
}
In this case, GCC creates the code for the necessary code generation for you. The downside is, that it limits you to the GNU compiler collection, and that the NX bit cannot be used on the stack anymore, as even your code will require new code on the stack.
makecallback() is called from the high-level code to create a new anonymous callback function with encapsulated state. If this new function is called, it will call the statefull callback function cb with arg state. The new anonymous callback function is useable, as long, as makecallback() does not return. Therefore, makecallback() returns control to the calling code by calling the passed in "cont" function. This example assumes, that the actual callback cb() and the normal continue function cont() both use the same state, "state". It is also possible to use two different void pointers to pass different state to both.
The "cont" function may only return (and SHOULD also return to avoid memory leaks), when the callback is no longer required. If your application is multi-threaded, and requires the various callbacks mostly for its various threads, then you should be able to have each thread at startup allocate its required callback(s) via makecallback().
However, if your app is multi-threaded anyways, and if you have (or can establish) a strict callback-to-thread relationship, then you could use thread-local vars to pass the required state. Of course, that will only work, if your lib calls the callback in the right thread.

Is calling a function (or virtual function) a costly operation in C++

I'm developing an application which is heavily based on math (sin, cos, sqrt etc).
These functions take some time to run but have high precision.
Some of my clients don't need that high precision, but they need it to be as fast as possible.
So I have my Sin function which is a simple array (which is created before the program starts to run) that takes a degree between 0 and 360 and returns its sin (let's say the array has 360 values).
I want to create an interface:
interface MyMath
{
double PreciseSin(double x);
double PreciseCos(double x);
}
It will be inherited by
"Precise math" which implementation will call the normal sin,cos function.
"Fast math" which will use the array trick I explained earlier.
My code will use a variable of type "mymath" to do the calculations, and in the beginning it will be initialized with preciseMath or fastMath.
Finally my questions are:
How much penalty in time I will pay for calling a virtual function that calls "Math.sin" instead of calling it directly?
Will the compiler will be able to optimize it and understand that in case I initialize MyMath with PriciseMath all I want is to call the normal Sin and Cos functions?
Can I change my design to help the compiler understand and optimize my code?
Odds are that your sqrt, and trig functions will have a much higher cost then the function call, even if its virtual. However this looks like the perfect place to use templates. If you use them correctly you can completely remove the run time cost of the function calls as all of them can be inlined.
class PreciseMath{
public:
inline double sin(double sin){
//code goes here
}
inline double cos(double sin){
//code goes here
}
inline double sqrt(double sin){
//code goes here
}
};
class FastMath{
public:
inline double sin(double sin){
//code goes here
}
inline double cos(double sin){
//code goes here
}
inline double sqrt(double sin){
//code goes here
}
};
template<class T>
class ExpensiveOP{
public:
T math;
void do(){
double x = math.sin(9);
x=math.cos(x);
//etc
}
}
ExpensiveOP<PreciseMath> preciseOp;
ExpensiveOP<FastMath> fasterOp;
For one and two:
You'll pay the same amount as calling a function through a function pointer. This isn't very much.
No, the compiler won't optimise virtual function calls into static function calls because it can't know that the type won't change at runtime somehow (like getting a pointer from some outside code that it doesn't know anything about). Delnan informed me in the comments that in very simple cases such as A* a = new A; a->func() the compiler can see that a will never be anything other than an A, so it can perform "devirtualisation" and optimise the virtual function call into a static function call. However, the cases where it can do this are somewhat rare, and if you got the pointer from, say, the argument to a function, it can't do this because it could actually be a derived type.
I don't know of any design that could make your code faster than that, besides "compile-time virtual functions" (aka. CRTP) but you lose polymorphism if you go this way. Try it with virtual functions and profile it; if it is too slow for you, then you can try another route, but don't waste time trying to make it faster without knowing how fast it already is.
How much penalty in time I will pay for calling a virtual function that calls "Math.sin" instead of calling it directly?
A virtual call is implemented by dereferencing the virtual table pointer, getting the function pointer from the appropriate offset in the virtual table and calling the function through that pointer.
This is slightly costlier than the static call, but is still considered very cheap for "normal" usage. If you need to squeeze every last drop of performance, consider specifying all your types at compile-time to allow usage of non-virtual functions.
Will the compiler will be able to optimize it and understand that in case I initialize MyMath with PriciseMath all I want is to call the normal Sin and Cos functions?
If compiler can prove (to itself) that an object will have a particular type at the run-time, then it will be able to emit a static function call, even when the function itself is declared as virtual.
However, the compiler is not guaranteed to be smart enough to actually do it. The only way to guarantee the static call is to use the non-virtual function.
Can I change my design to help the compiler understand and optimize my code?
Eliminate virtual call overhead: If there is no need to change the implementation at run-time, then specify the types at compile-time and stop using virtual functions altogether. Templates can be indispensable in doing so in a generic way.
Eliminate the static function call overhead: Provide function bodies in headers, allowing compiler to inline function calls.
(The RTS's answer is a nice illustration of both these techniques.)
And finally, if performance is really important to you, don't just rely on advice of other people (including me) - always perform the measurements yourself!
If you can provide different binaries, just do conditional compilation:
namespace MyMath {
#ifdef FAST_MATH
double sin(double x) { /* do it fast */ }
double sos(double x) { /* do it fast */ }
#else
double sin(double x) { /* do it precise */ }
double sos(double x) { /* do it precise */ }
#endif
}
And then call your compiler with -DFAST_MATH to generate the fast binary and without for the exact binary.

Easy way of calling function with unknown args count via pointer

I have the following code:
typedef void * (__stdcall * call_generic)(...);
typedef void * (__stdcall * call_push2)(unsigned long,unsigned long);
void * pfunc;
// assume pfunc is a valid pointer to external function
// this is a logically correct way of calling, however this includes:
// add esp, 8
// after the call, and that breaks my stack.
((call_generic)pfunc)(1,1);
// however, if i use this call:
((call_push2)pfunc)(1,1);
// this does not happen and code works properly.
It's a pain to track all the calls and count args manually (there are lots of such calls ahead), I'd prefer a macro or something for this, but with that bug it's not possible.
Is there a solution? Is there another way of creating call_generic type to do such things?
I do not really understand why exactly it does that "cleanup" but that breaks my stack badly, causing previously defined variables to be lost.
((call_generic)pfunc)(1,1); is only a logically correct way of calling if the function pointed to by pfunc actually has the signature you cast to, void *(...). Your code tells the compiler to make a varargs call, so it makes a varargs call. A varargs call to a function that isn't a varargs function doesn't work (in this case, there's disagreement who has to clean up the stack, and it gets done twice).
There's no way to do this for free. You must somehow cast the function pointer to the correct signature before calling it, otherwise the calling code doesn't know how to pass the parameters in a way that the callee code can use.
One option is to ensure that all the called functions that pfunc might point to have the same signature, then cast to that type. For example, you could make them all varargs functions, although I don't particularly recommend it. It would be more type safe to do what you don't want to - make sure that all the functions that might appear here take two unsigned long, and cast to call_push2.
The trick with call_generic won't work with functions that should be called with __stdcall calling convention. This is because __stdcall implies that the function should clean the stack, OTOH variadic functions (those with ... arguments) may not do this, since they are not aware of the arguments.
So that marking a variadic function with __stdcall calling convention is like shooting yourself in the foot.
In your specific case I'd go in the macro writing direction. I don't see a trivial trick that'd acomplish what you need.
EDIT
One of the techniques may be using template classes. For instance:
// any __stdcall function returning void taking 2 arguments
template <typename T1, typename T2>
struct FuncCaller_2
{
typedef void * (__stdcall * FN)(T1, T2);
static void Call(PVOID pfn, T1 t1, T2 t2)
{
((FN) pfn)(t1, t2);
}
};
// call your function
FuncCaller_2<int, long>::Call(pfn, 12, 19);
You'll need to create such a class for every number of arguments (0, 1, 2, 3, ...).
Needless to say this method is "unsafe" - i.e. there is no compile-time validation of the correctness of the function call.
seems to me you want a form of dynamic function binding mechanism that will bind a pointer to a protoype deducted from an invocation. This generally requires metaprogramming, for this boost::bind or something else from the boost functions library is your best bet (and if they don't have it, its doubtful that i can be done).

What is the point of function pointers?

I have trouble seeing the utility of function pointers. I guess it may be useful in some cases (they exist, after all), but I can't think of a case where it's better or unavoidable to use a function pointer.
Could you give some example of good use of function pointers (in C or C++)?
Most examples boil down to callbacks: You call a function f() passing the address of another function g(), and f() calls g() for some specific task. If you pass f() the address of h() instead, then f() will call back h() instead.
Basically, this is a way to parametrize a function: Some part of its behavior is not hard-coded into f(), but into the callback function. Callers can make f() behave differently by passing different callback functions. A classic is qsort() from the C standard library that takes its sorting criterion as a pointer to a comparison function.
In C++, this is often done using function objects (also called functors). These are objects that overload the function call operator, so you can call them as if they were a function. Example:
class functor {
public:
void operator()(int i) {std::cout << "the answer is: " << i << '\n';}
};
functor f;
f(42);
The idea behind this is that, unlike a function pointer, a function object can carry not only an algorithm, but also data:
class functor {
public:
functor(const std::string& prompt) : prompt_(prompt) {}
void operator()(int i) {std::cout << prompt_ << i << '\n';}
private:
std::string prompt_;
};
functor f("the answer is: ");
f(42);
Another advantage is that it is sometimes easier to inline calls to function objects than calls through function pointers. This is a reason why sorting in C++ is sometimes faster than sorting in C.
Well, I generally use them (professionally) in jump tables (see also this StackOverflow question).
Jump tables are commonly (but not exclusively) used in finite state machines to make them data driven. Instead of nested switch/case
switch (state)
case A:
switch (event):
case e1: ....
case e2: ....
case B:
switch (event):
case e3: ....
case e1: ....
you can make a 2d array of function pointers and just call handleEvent[state][event]
Examples:
Custom sorting/searches
Different
patterns (like Strategy, Observer)
Callbacks
The "classic" example for the usefulness of function pointers is the C library qsort() function, which implements a Quick Sort. In order to be universal for any and all data structures the user may come up with, it takes a couple of void pointers to sortable data and a pointer to a function that knows how to compare two elements of these data structures. This allows us to create our function of choice for the job, and in fact even allows for choosing the comparison function at run time, e.g. for sorting ascending or descending.
Agree with all of the above, plus....
When you load a dll dynamically at runtime you'll need function pointers to call the functions.
In C, the classic use is the qsort function, where the fourth parameter is pointer to a function to use to perform the ordering within the sort. In C++, one would tend to use functors (objects that look like functions) for this kind of thing.
I am going to go against the current here.
In C, function pointers are the only way to implement customization, because there is no OO.
In C++, you can use either function pointers or functors (function objects) for the same result.
The functors have a number of advantages over raw function pointers, due to their object nature, notably:
They may present several overloads of the operator()
They can have state / reference to existing variables
They can be built on the spot (lambda and bind)
I personally prefer functors to function pointers (despite the boilerplate code), mostly because the syntax for function pointers can easily get hairy (from the Function Pointer Tutorial):
typedef float(*pt2Func)(float, float);
// defines a symbol pt2Func, pointer to a (float, float) -> float function
typedef int (TMyClass::*pt2Member)(float, char, char);
// defines a symbol pt2Member, pointer to a (float, char, char) -> int function
// belonging to the class TMyClass
The only time I have ever seen function pointers used where functors could not was in Boost.Spirit. They have utterly abused the syntax to pass an arbitrary number of parameters as a single template parameter.
typedef SpecialClass<float(float,float)> class_type;
But since variadic templates and lambdas are around the corner, I am not sure we will use function pointers in pure C++ code for long now.
I used function pointers recently to create an abstraction layer.
I have a program written in pure C that runs on embedded systems. It supports multiple hardware variants. Depending on the hardware I am running on, it needs to call different versions of some functions.
At initialization time, the program figures out what hardware it is running on and populates the function pointers. All of the higher-level routines in the program just call the functions referenced by pointers. I can add support for new hardware variants without touching the higher-level routines.
I used to use switch/case statements to select the proper function versions, but this became impractical as the program grew to support more and more hardware variants. I had to add case statements all over the place.
I also tried intermediate function layers to figure out which function to use, but they didn't help much. I still had to update case statements in multiple places whenever we added a new variant. With the function pointers, I only have to change the initialization function.
Function pointers can be used in C to create an interface against which to program. Depending on the specific functionality that is needed at runtime, a different implementation can be assigned to the function pointer.
My main use of them has been CALLBACKS: when you need to save information about a function to call later.
Say you're writing Bomberman. 5 seconds after the person drops the bomb, it should explode (call the explode() function).
Now there's 2 ways to do it. One way is by "probing" all bombs on the screen to see if they're ready to explode in the main loop.
foreach bomb in game
if bomb.boomtime()
bomb.explode()
Another way is to attach a callback to your clock system. When a bomb is planted, you add a callback to make it call bomb.explode() when the time is right.
// user placed a bomb
Bomb* bomb = new Bomb()
make callback( function=bomb.explode, time=5 seconds ) ;
// IN the main loop:
foreach callback in callbacks
if callback.timeToRun
callback.function()
Here callback.function() can be any function, because it is a function pointer.
Like Rich said above, it is very usual for functions pointers in Windows to reference some address that stores function.
When you programming in C language on Windows platform you basically load some DLL file in primary memory(using LoadLibrary) and to use the functions stored in DLL you need to create functions pointers and point to these address (using GetProcAddress).
References:
LoadLibrary
GetProcAddress
Use of function pointer
To call function dynamically based on user input.
By creating a map of string and function pointer in this case.
#include<iostream>
#include<map>
using namespace std;
//typedef map<string, int (*)(int x, int y) > funMap;
#define funMap map<string, int (*)(int, int)>
funMap objFunMap;
int Add(int x, int y)
{
return x+y;
}
int Sub(int x, int y)
{
return x-y;
}
int Multi(int x, int y)
{
return x*y;
}
void initializeFunc()
{
objFunMap["Add"]=Add;
objFunMap["Sub"]=Sub;
objFunMap["Multi"]=Multi;
}
int main()
{
initializeFunc();
while(1)
{
string func;
cout<<"Enter your choice( 1. Add 2. Sub 3. Multi) : ";
int no, a, b;
cin>>no;
if(no==1)
func = "Add";
else if(no==2)
func = "Sub";
else if(no==3)
func = "Multi";
else
break;
cout<<"\nEnter 2 no :";
cin>>a>>b;
//function is called using function pointer based on user input
//If user input is 2, and a=10, b=3 then below line will expand as "objFuncMap["Sub"](10, 3)"
int ret = objFunMap[func](a, b);
cout<<ret<<endl;
}
return 0;
}
This way we have used function pointer in our actual company code.
You may write 'n' number of function and call them using this method.
OUTPUT:
Enter your choice( 1. Add 2. Sub 3. Multi) : 1
Enter 2 no :2 4
6
Enter your choice( 1. Add 2. Sub 3. Multi) : 2
Enter 2 no : 10 3
7
Enter your choice( 1. Add 2. Sub 3. Multi) : 3
Enter 2 no : 3 6
18
A different perspective, in addition to other good answers here:
In C, you only use function pointers, not (directly) functions.
I mean, you write functions, but you cant manipulate functions. There's no run-time representation of a function as such which you are able to use. You can't even call "a function". When you write:
my_function(my_arg);
what you're actually saying is "perform a call to the my_function pointer with the specified argument". You're making a call via a function pointer. This decay to function pointer means that the following commands are equivalent to the previous function call:
(&my_function)(my_arg);
(*my_function)(my_arg);
(**my_function)(my_arg);
(&**my_function)(my_arg);
(***my_function)(my_arg);
and so on (thanks #LuuVinhPhuc).
So, you're already using function pointers as values. Obviously you would want to have variables for those values - and here is where all the uses other metion come in: Polymorphism/customization (like in qsort), callbacks, jump tables etc.
In C++ things are a bit more complicated, since we have lambdas, and objects with operator(), and even an std::function class, but the principle is still mostly the same.
I use function pointers extensively, for emulating microprocessors that have 1-byte opcodes. An array of 256 function pointers is the natural way to implement this.
For OO languages, to perform polymorphic calls behind the scenes (this is also valid for C up to some point I guess).
Moreover, they're very useful to inject different behaviour to another function (foo) at runtime. That makes function foo higher-order function. Besides it's flexibility, that makes the foo code more readable since it let's you pull that extra logic of "if-else" out of it.
It enables many other useful things in Python like generators, closures etc.
One use of function pointer could be where we may not want to modify the code where the function is getting called (meaning thereby the call might be conditional and under different conditions, we need to do different sort of processing).
Here the function pointers are very handy, since we do not need to modify the code at the the place where the function is getting called. We simply call the function using the function pointer with appropriate arguments.
The function pointer can be made to point to different functions conditionally. (This can be done somewhere during initialization phase). Moreover the above model is very helpful, if we are not in position to modify the code where it is getting called (suppose it's a library API we can't modify). The API uses a function pointer for calling the appropriate user defined function.
I'll try to give a somewhat comprehensive list here:
Callbacks: Customize some (library) functionality with user supplied code. Prime example is qsort(), but also useful to handle events (like a button calling a callback when it's clicked), or necessary to start a thread (pthread_create()).
Polymorphism: The vtable in a C++ class is nothing but a table of function pointers. And a C program may also choose to provide a vtable for some of its objects:
struct Base;
struct Base_vtable {
void (*destruct)(struct Base* me);
};
struct Base {
struct Base_vtable* vtable;
};
struct Derived;
struct Derived_vtable {
struct Base_vtable;
void (*frobnicate)(struct Derived* me);
};
struct Derived {
struct Base;
int bar, baz;
}
The constructor of Derived would then set its vtable member variable to a global object with the derived's class's implementations of destruct and frobnicate, and code that needed to destruct a struct Base* would simply call base->vtable->destruct(base), which would call the correct version of the destructor, independent of which derived class base actually points to.
Without function pointers, polymorphism would need to be coded out with an army of switch constructs like
switch(me->type) {
case TYPE_BASE: base_implementation(); break;
case TYPE_DERIVED1: derived1_implementation(); break;
case TYPE_DERIVED2: derived2_implementation(); break;
case TYPE_DERIVED3: derived3_implementation(); break;
}
This gets rather unwieldy rather quickly.
Dynamically loaded code: When a program loads a module into memory and tries to call into its code, it must go through a function pointer.
All the uses of function pointers that I've seen fall squarely into one of these three broad classes.
They enhance re-use and modularization of code thus making code more maintainable, readable and less prone to errors.
With function pointers:
Note how we have an iterator method that gets passed to it a function pointer. This function pointer tells us what we should do with each elements in the list.
#include <iostream>
#include <vector>
int square(int x) {
return x * x;
}
int root(int x) {
return sqrt(x);
}
int negative(int x) {
return -x;
}
std::vector<int> listIterator(std::vector<int> list, int (*itemOperation)(int)) {
for (int i = 0; i < list.size(); i++) {
list[i] = itemOperation(list[i]);
}
return list;
}
int main() {
std::vector<int> list = { 9, 16, 4, 25 };
for (int i : listIterator(list, square)) {
std::cout << i << ' ';
}
std::cout << std::endl;
for (int i : listIterator(list, root)) {
std::cout << i << ' ';
}
std::cout << std::endl;
for (int i : listIterator(list, negative)) {
std::cout << i << ' ';
}
return 0;
}
Without function pointers:
Without function pointers, you would need to include an iterator in each of the square, root and negative methods.