views:

2843

answers:

10

I have been programming for a few years now and have used function pointers in certain cases. What I would like to know is when is it appropriate or not to use them for performance reasons and I mean in the context of games, not business software.

Function pointers are fast, John Carmack used them to the extent of abuse in the Quake and Doom source code and because he is a genius :)

I would like to use function pointers more but I want to use them where they are most appropriate.

These days what are the best and most practical uses of function pointers in modern c-style languages such as C, C++, C# and Java, etc?

+6  A: 

Any time you use a event handler or delegate in C#, you are effectively using a function pointer.

And no, they are not about speed. Function pointers are about convenience.

Jonathan

Jonathan Allen
+5  A: 

Function pointers are used as callbacks in many cases. One use is as a comparison function in sorting algorithms. So if you are trying to compare customized objects, you can provide a function pointer to the comparison function that knows how to handle that data.

That said, I'll provide a quote I got from a former professor of mine:

Treat a new C++ feature like you would treat a loaded automatic weapon in a crowded room: never use it just because it looks nifty. Wait until you understand the consequences, don't get cute, write what you know, and know what you write.

Kyle Walsh
haha, that is so true! reminds me of http://www.gotw.ca/publications/advice97.htm :)
Johannes Schaub - litb
That's exactly what he was referencing! Awesome.
Kyle Walsh
"Write what you know" works if you work alone on the project. But if you good at **arrays and not familiar with STL it is not cool to work in one team then. Same things with pure C like functions around the code in the big project.
Mykola Golubyev
good quote. See Syntaxophilia: http://www.mischel.com/rants/syntaxophilia.htm
Jim Mischel
+2  A: 

Just speaking of C#, but function pointers are used all over C#. Delegates and Events (and Lambdas, etc) are all function pointers under the hood, so nearly any C# project is going to be riddled with function pointers. Basically every event handler, near every LINQ query, etc - will be using function pointers.

Reed Copsey
+1  A: 

Function pointers are fast

In what context? Compared to?

It sounds like you just want to use function pointers for the sake of using them. That would be bad.

A pointer to a function is normally used as a callback or event handler.

Fast in the sense that they are effectively a jump to another part of your code that saves you from returning in the current method and probably leaving your loop and then returning later.
Brock Woolf
I see your point though and agree, shouldn't use them just for the sake of it.
Brock Woolf
Regular function calls are also "a jump to another part of your code". Yes, this is useful behavior, but you usually get it by plain function calls, there's no need to involve function pointers
jalf
+3  A: 

These days what are the best and most practical uses of integers in modern c-style languages?

anon
I apologise but i do not follow?
Brock Woolf
If you need an integer, use an integer. If you need a function pointer, use a function pointer. Both (like all programming constructs) are just tools, neither is especially fast or magical in any way.
anon
I, for one, enjoy your sarcasm, sir.
Marcin
hah ;)Funny, but not very helpful
jalf
Give yourself a bit pat on the back *golf claps*
Brock Woolf
i enjoy you too. you certainly go up one point now ahaha
Johannes Schaub - litb
+6  A: 

They can be useful if you do not know the functionality supported by your target platform until run-time (e.g. CPU functionality, available memory). The obvious solution is to write functions like this:

int MyFunc()
{
  if(SomeFunctionalityCheck())
  {
    ...
  }
  else
  {
    ...
  }
}

If this function is called deep inside of important loops then its probably better to use a function pointer for MyFunc:

int (*MyFunc)() = MyFunc_Default;

int MyFunc_SomeFunctionality()
{
  // if(SomeFunctionalityCheck())
  ..
}

int MyFunc_Default()
{
  // else
  ...
}

int MyFuncInit()
{
  if(SomeFunctionalityCheck()) MyFunc = MyFunc_SomeFunctionality;
}

There are other uses of course, like callback functions, executing byte code from memory or for creating an interpreted language.

To execute Intel compatible byte code on Windows, which might be useful for an interpreter. For example, here is an stdcall function returning 42 (0x2A) stored in an array which can be executed:

code = static_cast<unsigned char*>(VirtualAlloc(0, 6, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
// mov eax, 42
code[0] = 0x8b;
code[1] = 0x2a;
code[2] = 0x00;
code[3] = 0x00;
code[4] = 0x00;
// ret
code[5] = 0xc3;
// this line executes the code in the byte array
reinterpret_cast<unsigned int (_stdcall *)()>(code)();

...

VirtualFree(code, 6, MEM_RELEASE);

);

jheriko
Really insightful, thanks for the code example
Brock Woolf
There should be Strategy or Some other like Decorator design pattern. Of course if we talk about C++.
Mykola Golubyev
+19  A: 

There is nothing especially "fast" about function pointers. They allow you to call a function which is specified at runtime. But you have exactly the same overhead as you'd get from any other function call (plus the additional pointer indirection). Further, since the function to call is determined at runtime, the compiler can typically not inline the function call as it could anywhere else. As such, function pointers may in some cases add up to be significantly slower than a regular function call.

Function pointers have nothing to do with performance, and should never be used to gain performance.

Instead, they are a very slight nod to the functional programming paradigm, in that they allow you to pass a function around as parameter or return value in another function.

A simple example is a generic sorting function. It has to have some way to compare two elements in order to determine how they should be sorted. This could be a function pointer passed to the sort function, and in fact c++'s std::sort() can be used exactly like that. If you ask it to sort sequences of a type that does not define the less than operator, you have to pass in a function pointer it can call to perform the comparison.

And this leads us nicely to a superior alternative. In C++, you're not limited to function pointers. You often use functors instead - that is, classes that overload the operator(), so that they can be "called" as if they were functions. Functors have a couple of big advantages over function pointers:

  • They offer more flexibility: they're full-fledged classes, with constructor, destructor and member variables. They can maintain state, and they may expose other member functions that the surrounding code can call.
  • They are faster: unlike function pointers, whose type only encode the signature of the function (a variable of type void (*)(int) may be any function which takes an int and returns void. We can't know which one), a functor's type encodes the precise function that should be called (Since a functor is a class, call it C, we know that the function to call is, and will always be, C::operator()). And this means the compiler can inline the function call. That's the magic that makes the generic std::sort just as fast as your hand-coded sorting function designed specifically for your datatype. The compiler can eliminate all the overhead of calling a user-defined function.
  • They are safer: There's very little type safety in a function pointer. You have no guarantee that it points to a valid function. It could be NULL. And most of the problems with pointers apply to function pointers as well. They're dangerous and error-prone.

Function pointers (in C) or functors (in C++) or delegates (in C#) all solve the same problem, with different levels of elegance and flexibility: They allow you to treat functions as first-class values, passing them around as you would any other variable. You can pass a function to another function, and it will call your function at specified times (when a timer expires, when the window needs redrawing, or when it needs to compare two elements in your array)

As far as I know (and I could be wrong, because I haven't worked with Java for ages), Java doesn't have a direct equivalent. Instead, you have to create a class, which implements an interface, and defines a function (call it Execute(), for example). And then instead of calling the user-supplied function (in the shape of a function pointer, functor or delegate), you call foo.Execute(). Similar to the C++ implementation in principle, but without the generality of C++ templates, and without the function syntax that allows you to treat function pointers and functors the same way.

So that is where you use function pointers: When more sophisticated alternatives are not available (ie. you are stuck in C), and you need to pass one function to another. The most common scenario is a callback. You define a function F that you want the system to call when X happens. So you create a function pointer pointing to F, and pass that to the system in question.

So really, forget about John Carmack and don't assume that anything you sees in his code will magically make your code better if you copy it. He used function pointers because the games you mention were written in C, where superior alternatives are not available, and not because they are some magical ingredient whose mere existence makes code run faster.

jalf
"Function pointers have nothing to do with performance, and should never be used to gain performance."Actually they can be used to improve performance, and so can functors/delegates etc. See the example in my answer... why should this never be done? I don't see whats bad about it.
jheriko
True. My point was simply that merely calling a function pointer instead of calling the function is not faster, as that seemed to be what the OP was implying. You're right, if you use it to change the logic of the program, it can affect performance as well.
jalf
+4  A: 

In the dim, dark ages before C++, there was a common pattern I used in my code which was to define a struct with a set of function pointers that (typically) operated on that struct in some way and provided particular behaviors for it. In C++ terms, I was just building a vtable. The difference was that I could side-effect the struct at runtime to change behaviors of individual objects on the fly as needed. This offers a much richer model of inheritance at the cost of stability and ease of debugging. The greatest cost, however, was that there was exactly one person who could write this code effectively: me.

I used this heavily in a UI framework that let me change the way objects got painted, who was the target of commands, and so on, on the fly - something that very few UIs offered.

Having this process formalized in OO languages is better in every meaningful way.

plinth
Exactly. I have used code references in several languages to emulate OO. FYI: not all languages "close" classes. Ruby, Javascript and Objective C let you do what you said about changing implementations at runtime.
Roboprog
+4  A: 

Function pointers are a poor man's attempt to be functional. You could even make an argument that having function pointers makes a language functional, since you can write higher order functions with them.

Without closures and easy syntax, they're sorta gross. So you tend to use them far less than desireable. Mainly for "callback" functions.

Sometimes, OO design works around using functions by instead creating a whole interface type to pass in the function needed.

C# has closures, so function pointers (which actually store an object so it's not just a raw function, but typed state too) are vastly more usable there.

Edit One of the comments said there should be a demonstration of higher order functions with function pointers. Any function taking a callback function is a higher order function. Like, say, EnumWindows:

BOOL EnumWindows(          
    WNDENUMPROC lpEnumFunc,
    LPARAM lParam
);

First parameter is the function to pass in, easy enough. But since there are no closures in C, we get this lovely second parameter: "Specifies an application-defined value to be passed to the callback function." That app-defined value allows you to manually pass around untyped state to compensate for lack of closures.

The .NET framework is also filled with similar designs. For instance, IAsyncResult.AsyncState: "Gets a user-defined object that qualifies or contains information about an asynchronous operation." Since the IAR is all you get on your callback, without closures, you need a way to shove some data into the async op so you can cast it out later.

MichaelGG
I'm curious why anyone voted this one down to -1. Seems like a correct (and well thought out) answer. +1 from here then to compensate.
jalf
+1, totally agree with jalf -- WTF?
j_random_hacker
I didn't downvote, but perhaps he should demonstrate how to constuct higher order functions with fps?
anon
+1  A: 

There are occasions when using function pointers can speed up processing. Simple dispatch tables can be used instead of long switch statements or if-then-else sequences.

Tim Ring