Richard Harter's World
Site map
September 2008
Mathcomp
email

Function pointer vs switch cases

The question at hand is to discuss the use of function pointers as a replacement for using switch cases. Here is my take.

There are three levels of simple transfer commands aka gotos. They are:

  1. The simple goto. The statement has the command verb and a fixed target label. It transfers control to the code marked by the target label.
  2. The computed goto, aka switch, select, or caseof, depending on the language. In C it is the switch. The essence of the computed goto is a fixed list of (value,label) pairs and an expression that can yield one of the values in the list. Control is transferred to the label corresponding to the value of the expression.

    The computed goto can either be structured or unstructured. In the unstructured form the labels can be anywhere within the source code unit. In the structured form there is a block associated the computed goto and the labels are all within the block. The C switch statement is a structured computed goto, albeit with some caveats about being structured.

  3. The variable goto. The statement has a command verb and a label variable. It transfers control to the label that is the value of the label variable. Standard C does not have the variable goto, although gcc (and I presume other compilers) offer variants of it as a standard extension.
It can be shown that the computed goto/switch is a stronger flow control construct than the goto, and that the variable goto is stronger than the computed goto, where strength means that more compact and more efficient code can be written user the stronger construct.

A function invocation is a variable goto with the caveat that control must be returned to the calling function after the called function. In C the code within the called function has a different scope than the scope within the calling function. This is also true in most other languages although there are many caveats.

Now what does this have to do with function pointers and switch cases? Function pointers provide a way to get around using switches. Instead of transferring control to a case label we invoke a function that is the value of variable containing a function pointer. Instead of having a list of (value,label) pairs we have a list of (value,function pointer) pairs.

We can express this list in many ways, depending on what the values are. Unlike the switch cases the values don't have to be integers. If they are the integers in the range 0:n-1 the list can be an array of function pointers and instead of having a switch statement and a list of cases with their code we have something like

	func[i](args);
On the other hand if the values are strings we could have an array of (key,function) pairs, search the array for the key, and invoke the corresponding function.

The great advantage of this sort of thing is that we can replace large switch statements within a single function with a series of small functions, each handling a single case. The resulting code (may be) is more compact and more readable.

However there are some gotchas. The two big ones are scope and signature.

In a switch block the code within the cases is within the scope of the containing function. What this means is that the code within the case has access to the variables in the function containing the switch. When you use the function pointer technique, the called functions don't automatically have access to the variables of the calling function. (You can fake it by passing them through the calling sequence.) As a result the called functions may have to do a bunch of makeup work.

The other gotcha is the signature problem. As a practical matter all of the functions in the (value,function) list must have the same prototype (signature) because they all are going to be called the same way. What this means is that these functions ususally have to be specially written within the context of being equivalent to replacing a switch.


This page was last updated August 1, 2008.

Richard Harter's World
Site map
September 2008
Mathcomp
email