views:

763

answers:

10

Hi, I have trouble seing the utility of the 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++)?

Many thanks :)

+13  A: 

Examples:

  1. Custom sorting/searches
  2. Different patters (like Strategy, Observer)
  3. Callbacks
Andrey
@Andrey +1 for the good examples.
Ikaso
Jump table is one of the important use of it.
Ashish
If there were some worked examples, this would get my upvote.
Donal Fellows
Strategy and observer are probably better implemented using virtual functions, if C++ is available. Otherwise +1.
Billy ONeal
i think that wise use of function pointers can make observer more compact and light weight
Andrey
+2  A: 

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.

dafmetal
+5  A: 

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.

anon
Don't forget `bsearch`!
Billy ONeal
@Billy: `pthread_create`, `sigaction`… the list is endless.
KennyTM
@KennyTM: I was pointing out the only other instance of this in the C standard library. The examples you cite are part of third party libraries.
Billy ONeal
+7  A: 

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.

Carl Smotricz
Don't forget `bsearch`!
Billy ONeal
+2  A: 

You can find quite a bit of discussion about function pointers in this related SO question.

itsmatt
+37  A: 

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.

sbi
+1 for the only example here with actual **code**!
Billy ONeal
+4  A: 

Agree with all of the above, plus.... When you load a dll dynamically at runtime you'll need function pointers to call the functions.

Rich
I do this all the time to support Windows XP and still use Windows 7 goodies. +1.
Billy ONeal
+3  A: 

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.

Matthieu M.
+12  A: 

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 or function pointers and just call handleEvent[state][event]

Mawg
+1 Interesting.
Rich
+1 I've never thought to go multi-dimensional with this.
itsmyown
+3  A: 

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.

msemack