gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > What are Function Pointers

#27994 - QuantumDoja - Mon Oct 25, 2004 9:01 pm

Hi, I know what a pointer is, but what is a function pointer?
_________________
Chris Davis

#27996 - Abscissa - Mon Oct 25, 2004 9:06 pm

It's basically just what it sounds. A function pointer is a pointer to a function, just like an int pointer is a pointer to an int.

If you're familiar with any newer languages like Java, C# or D, then it's like a primitive version of a delegate.

#28002 - sajiimori - Mon Oct 25, 2004 10:27 pm

Pick up a good C book -- I recommend the "C Primer Plus".

#28025 - pan69 - Tue Oct 26, 2004 7:32 am

http://www.function-pointer.org/

#28032 - yaustar - Tue Oct 26, 2004 11:50 am

I know what they are myself but I still dont understand what are they used for. Someone said something about 'dynamically changing the flow of the program at run time' :S
_________________
[Blog] [Portfolio]

#28035 - poslundc - Tue Oct 26, 2004 2:11 pm

yaustar wrote:
I know what they are myself but I still dont understand what are they used for. Someone said something about 'dynamically changing the flow of the program at run time' :S


Because a function-pointer can point to any function, it means I could have, for example, a game where every loop I call a function to draw the screen. Normally it draws the cars and the racetrack, but when someone switches to the menu mode I can change it to instead point to a function that draws the menus.

Taken to a more sophisticated level, I could have structs to represent generic characters in my game, containing sprite-related data that all the characters require, but a function pointer that can point to different functions depending on what the character is supposed to actually do in the game. This is one of the underlying concepts that polymorphism (that's so popular in object-oriented languages) is based upon.

There are other things you can do as well, such as have an array of function pointers and then use an index into that array to choose which function to call, depending on what you are trying to do. This is how single interrupt support was implemented in Devkit Advance (if you did things the PERN way, and probably many other tutorials as well).

Basically, it gives you an abstract way to have your code call a function, without specifying what function it is that will be called. This is what is meant by dynamically changing the flow at runtime.

Dan.

#28048 - jma - Tue Oct 26, 2004 4:10 pm

yaustar wrote:
I know what they are myself but I still dont understand what are they used for.


They are most commonly used in state machines, bytecode interpreters, etc. Anything that typically links a number to a function call. It is much better to do this that a series of if statements or a giant switch statement with hundreds of cases. Here's a trivial example (with declarations missing for readability):

Code:
typedef void (*state)();

// the one and only global game state
static state g_state = title_screen();

void title_screen() {
  draw_main_menu();
  if (user_selection() == new_game) {
    g_state = load_game;
  }
}

void load_game() {
  load_all_level_graphics();
  g_state = play_game();
}

void play_game() {
  draw_game();
  accept_input();
  if (game_over == true) {
    g_state = title_screen;
  }
}

void main() {
  while(1) {
    vblank();
    g_state();
  }
}


As you can see, this simple state-machine makes the main game loop extremely simple. It doesn't actually do anything other than wait for a vertical blank, then call the current game function. Each state function is resposible for progressing the "machine" along to the next state.

Jeff
_________________
massung@gmail.com
http://www.retrobyte.org

#28115 - yaustar - Wed Oct 27, 2004 12:13 am

Does it help a little with code optimsiation as I remember (abliet vaugely) that if/switch statements create branches in the code where a function pointer seems to avoid it altogether?
_________________
[Blog] [Portfolio]

#28121 - Gene Ostrowski - Wed Oct 27, 2004 12:54 am

To an extent, yes.

In a highly contrived scenario, assume you have a routine that plots pixels. You then want to create a version that plots one for an 8-bit screen, a 16-bit screen, a 24-bit screen, a 32-bit screen, etc.

Then, you have a structure that maintains the "display" information (resolution, bit-depth, etc.). You could also save the pointer to the "proper" draw function so that when you can call:

screen->plotPixel(x,y,color)

...the system will know which "version" of the routine to use since it's pointing to the one that corresponds to the type of display.

It keeps you from having to code the routine in some variation of the following:

plotPixel(x,y,color)
{
if (screen->depth==8) { // plot it in 8 bit }
else if (screen->depth==16) { // plot it in 16-bit }
else if (screen->depth==24) { // plot it in 24-bit }
...
}

If you can get past the C vs C++ debate of the thread, and the "validity" of using function pointers for this in C, I posted some information about exactly this topic in http://forum.gbadev.org/viewtopic.php?t=4257
_________________
------------------
Gene Ostrowski