I have come across the fact that function pointers can be used to implement callbacks. Is there any other usage of function pointers? Is there any other situation that function pointers proved to be useful?
How about sorting? Pass in a function pointer to compare any two elements.
How about filtering? Pass in a function pointer to decide whether an input element should be contained in the output of a filter.
How about transformations? Pass in a function pointer to convert an input element to an output element.
These are all collection-based uses, but they're very useful. (The broad equivalent of function pointers in .NET is delegates, and they're the basis of LINQ, which allows very simple querying, transformations, grouping etc.)
Anywhere you want to be able to abstract out the idea of "a single piece of behaviour", writing a generic function which doesn't need to know the details of that behaviour, a function pointer could be useful.
In addition to what Jon wrote, function pointers in C can be used to implement OO programming style (e.g. polymorphism).
Function pointers (or their typed and more advanced equivalents) are a helpful feature when implementing inversion of control related patterns. All examples mentioned are applications of IoC principle (the sorting algorithm does not control the used predicate, the call to an object method is delayed until run-time etc)
Regards,
Paul
A function pointer is used in any situation where the function to be called is determined at runtime rather than compile-time. This includes callbacks, but may also be used as a switch-case alternative for example, and to adapt the behaviour of a function by passing a function pointer that defines that behaviour - this is how the standard library qsort() function works for example, enabling it to sort any kind of object.
I have used them in particular to implement a command line parser that evaluates C expressions entered as strings at run-time, and can include function calls. This uses a symbol table to lookup the pointer to the function so it can be called on demand from the operator.
All you might ever wish to know on the subject can be found at The Function Pointer Tutorials
In the end function pointers are just one of those rarely used tools you keep in your bag. If you understand them, when the situation arises where it may provide a solution, you will hopefully recognise it.
It is the only way you can implement Higher Order Functions in C.
As others have mentioned, I've found that one of the most significant uses of function pointers (other than for callbacks) is to enable the construction of generic data structures.
Say you want to construct a hashmap with arbitrary keys and values. One way to do that is declare both void *key and void *value and then pass in two function pointers during the initialization phase: int (*hashcode)(void*) and int (*equals)(void*, void*).
This gives you the ability to build a hashmap that can take basically anything that you can write the above two functions for. In my case, the key was a fixed size character buffer and the value was a pointer to a struct.
It is also used in the following
Making jump tables(like vector tables or ISR)
making the function abstract
Developing Finite State Machines (as state, action and triggered even can easily be implemented using the function pointers, the design also seems to be easy and more readable in that)
Event Driven Framework(GUI - gtk is an example)
Other than callbacks (great for abstraction), function pointers can be used to implement polymorphism in C. This is done extensively in the Linux kernel, and common C libraries such as glibc, GTK+ and GLib.
Related
There are no classes in C, but it is simple enough to create something similar by defining a struct that contains all the "class"'s properties, and representing its methods by functions that take pointers to said struct as their first arguments. I am in the process of documenting a header file of this form.
I'm trying to figure out how to refer to this sort of function without using object-oriented terminology like "method". I could just invent my own name for it and define it, but considering how common these sort of functions are, I assume there's already a standard way to refer to them. Am I correct? If so, how do I refer to them?
I would use both "function" and "method".
"Function" would refer to the implementation, since it is actually a function, not a method.
"Method" would refer to how the function is used, since you want to emulate OOP, and you even call it as-if it would be a method. Of course, you will not be able to use advanced OOP features of the "method", but you accepted that when you decided to use C instead of C++.
I would call them methods.
If Rust can call it methods, sure you can.
I'd like to be able to generically pass a function to a function in C. I've used C for a few years, and I'm aware of the barriers to implementing proper closures and higher-order functions. It's almost insurmountable.
I scoured StackOverflow to see what other sources had to say on the matter:
higher-order-functions-in-c
anonymous-functions-using-gcc-statement-expressions
is-there-a-way-to-do-currying-in-c
functional-programming-currying-in-c-issue-with-types
emulating-partial-function-application-in-c
fake-anonymous-functions-in-c
functional-programming-in-c-with-macro-higher-order-function-generators
higher-order-functions-in-c-as-a-syntactic-sugar-with-minimal-effort
...and none had a silver-bullet generic answer, outside of either using varargs or assembly. I have no bones with assembly, but if I can efficiently implement a feature in the host language, I usually attempt to.
Since I can't have HOF easily...
I'd love higher-order functions, but I'll settle for delegates in a pinch. I suspect that with something like the code below I could get a workable delegate implementation in C.
An implementation like this comes to mind:
enum FUN_TYPES {
GENERIC,
VOID_FUN,
INT_FUN,
UINT32_FUN,
FLOAT_FUN,
};
typedef struct delegate {
uint32 fun_type;
union function {
int (*int_fun)(int);
uint32 (*uint_fun)(uint);
float (*float_fun)(float);
/* ... etc. until all basic types/structs in the
program are accounted for. */
} function;
} delegate;
Usage Example:
void mapint(struct fun f, int arr[20]) {
int i = 0;
if(f.fun_type == INT_FUN) {
for(; i < 20; i++) {
arr[i] = f.function.int_fun(arr[i]);
}
}
}
Unfortunately, there are some obvious downsides to this approach to delegates:
No type checks, save those which you do yourself by checking the 'fun_type' field.
Type checks introduce extra conditionals into your code, making it messier and more branchy than before.
The number of (safe) possible permutations of the function is limited by the size of the 'fun_type' variable.
The enum and list of function pointer definitions would have to be machine generated. Anything else would border on insanity, save for trivial cases.
Going through ordinary C, sadly, is not as efficient as, say a mov -> call sequence, which could probably be done in assembly (with some difficulty).
Does anyone know of a better way to do something like delegates in C?
Note: The more portable and efficient, the better
Also, Note: I've heard of Don Clugston's very fast delegates for C++. However, I'm not interested in C++ solutions--just C .
You could add a void* argument to all your functions to allow for bound arguments, delegation, and the like. Unfortunately, you'd need to write wrappers for anything that dealt with external functions and function pointers.
There are two questions where I have investigated techniques for something similar providing slightly different versions of the basic technique. The downside of this is that you lose compile time checks since the argument lists are built at run time.
The first is my answer to the question of Is there a way to do currying in C. This approach uses a proxy function to invoke a function pointer and the arguments for the function.
The second is my answer to the question C Pass arguments as void-pointer-list to imported function from LoadLibrary().
The basic idea is to have a memory area that is then used to build an argument list and to then push that memory area onto the stack as part of the call to the function. The result is that the called function sees the memory area as a list of parameters.
In C the key is to define a struct which contains an array which is then used as the memory area. When the called function is invoked, the entire struct is passed by value which means that the arguments set into the array are then pushed onto the stack so that the called function sees not a struct value but rather a list of arguments.
With the answer to the curry question, the memory area contains a function pointer as well as one or more arguments, a kind of closure. The memory area is then handed to a proxy function which actually invokes the function with the arguments in the closure.
This works because the standard C function call pushes arguments onto the stack, calls the function and when the function returns the caller cleans up the stack because it knows what was actually pushed onto the stack.
A set of function pointers grouped
into a data structure are often
referred to as a virtual function
table (VFT).
The above statement makes me feel that virtual function == function pointer,is that so?
There is no built-in support for virtual functions in C.
In C++ virtual functions are specified via a v-table. And the entries in a vtable can be implemented as function pointers.
That’s wrong because these are different levels of abstraction.
An analogy may help: saying that virtual functions and function pointers are identical is like saying that wheels and bikes are identical.
While it’s true that function pointers and virtual functions may look much the same “under the hood”, they are different things – both conceptionally (a virtual function is an overriable member method of a class while a function pointer is simply an indirection of a function) and syntactically (calling them is completely different).
They may serve the same purpose, however. In particular, both provide a means of deferring a calling decision (which function to call in this situation?) until runtime when normal call dispatching happens at compile time.
I'd say close, but not quite. A virtual function is still a function, but it's normally called via a pointer, not directly.
Yes, a virtual function table is often implemented under the hood as a table of function pointers. However, there is also other hardware to go along with the table of pointers to make the functions actually "virtual". You have to have a mechanism in place to bind a call to the correct pointer at run-time, etc. I say this because it would be wrong to think that since a virtual function is a function pointer at its most basic level that that makes any function pointer a virtual function.
Actually C++ Supports Virtual Functions , but C Does not supports VF because both are totally different concepts
Virtual function in C++ by definition is a function declared with keyword virtual (immediately or in one of the base classes). That's all.
Now, calls to virtual functions can be resolved statically or dynamically. A dynamically-resolved call is a call that resolved in accordance with dynamic type of the object used in the call. That's all.
Nothing in the above has any references to any "function pointers". However, in a typical implementation in order to implement the proper behavior of dynamic calls, a table with function pointers (pointing to virtual functions) is used. This table is what is known as "VMT", "VFT" or "vtable".
In other words, function pointer is an implementation detail typically used to provide support for dynamic calls to virtual functions.
To illustrate it further, note, for example, that even if some function is virtual, but it is never called dynamically, then there's no need to generate any "pointers" for that function. For this reason, some compilers do not generate VMTs for abstract classes, since even though these classes have virtual functions, these functions are never called dynamically.
I guessed it's from the Understanding Linux Network Internals book -- We're talking about C here, and you've got your parenthesis wrong -- it's virtual (function table), not (virtual function) table :). Virtual functions are a C++ only term.
Which doesn't mean you can't code OOP in ANSI C...
Being a developer born and raised on OO, I was curious to hear how it's possible to avoid global state in a procedural program.
You can also write object-oriented code in C. You don't get all the C++ goodies and it's ugly, and you have to manually pass the this pointer (I've seen self used for this, in order to make it compatible with C++), but it works. So technically, you don't need global state in pure procedural languages for the very same reasons you don't need it in object-oriented languages. You just have to pass the state around explicitly, rather than implicitly like in OO languages.
As an example, look at how the file I/O functions in the C standard library work with pointer to FILE objects that are (largely) opaque. Or look at how OS APIs deal with handles and such to encapsulate information. A program creates objects, uses APIs that act on those objects and closes/deletes the objects - all using straight C.
A global variable is nothing but an implicit procedure argument. Make it explicit and the global variable goes away.
Note: the fact that you no longer use a global variable does not mean that you no longer use global state! What we did above was just a purely syntactical transformation, the semantics of the program haven't changed at all. It's just as non-composable, non-modular, non-threadsafe, non-parallelizable as it was before.
All OO is a mindset and a whole bunch of compiler support.
You can achieve much the same by discipline, coding conventions, and passing around structures in most languages.
For example I used to have functions/procedures prefixed with their module identity, taking the first parameter as being the related module struct.
// System.h
typedef struct _System
{
struct _System *owner;
LinkedList *elements;
} System;
// System.c
int System_FindName ( System * system, char *name)
{
..
}
etc..
I'd really seriously not like to have to go back to coding like this though. I'm very happy that I haven't had to write and debug a linked list for at least 18 years. It was hard back then without the internet and sitting there isolated in the corner of a cold brightly lit room with green phosphors burning into your retina...
Of course. Just declare a struct somewhere, allocate some memory for it, pass the pointer to the allocated memory to an initialization function, and off you go. Just pass the pointer to all the functions that require using the struct.
Though the question arises as to where you store the pointer to the data you don't want to be global, and then you may end up with a global pointer ;-)
You can have variables on stack or in heap that will exist during all the program life.
Passing object style structure pointers to every function is a good way to have OO C coding style.
(I would suggest to have a look in linux sources)
You could try, as an example, create with dia (the diagramming tool), a simple class (for example, a square).
http://projects.gnome.org/dia/
http://dia-installer.de/index_en.html
Then, you can transform that class in C code using dia2code:
http://dia2code.sourceforge.net/
Specifically, say you created the class square inside the square.dia diagram. Then, you type:
$ dia2code -t c square.dia
... and you will see that it is possible to convert any object-oriented programming in a C program without global variables. Explore the created files square.c and square.h
NOTE: in Windows, you'll need a workaround in order to make dia2code work. Before using dia2code, change square.dia to square.zip, unzip it, and rename the result as square.dia
Simple. Whenever a procedure accesses a global variable, then give this variable as an argument to the procedure instead, either by value or by reference or by pointer, or by whatever your programming language provides. After that there is no more need for the variable to be global.
It doesn't seem like it would be too hard to implement in assembly.
gcc also has a flag (-fnested-functions) to enable their use.
It turns out they're not actually all that easy to implement properly.
Should an internal function have access to the containing scope's variables?
If not, there's no point in nesting it; just make it static (to limit visibility to the translation unit it's in) and add a comment saying "This is a helper function used only by myfunc()".
If you want access to the containing scope's variables, though, you're basically forcing it to generate closures (the alternative is restricting what you can do with nested functions enough to make them useless).
I think GCC actually handles this by generating (at runtime) a unique thunk for every invocation of the containing function, that sets up a context pointer and then calls the nested function. This ends up being a rather Icky hack, and something that some perfectly reasonable implementations can't do (for example, on a system that forbids execution of writable memory - which a lot of modern OSs do for security reasons).
The only reasonable way to make it work in general is to force all function pointers to carry around a hidden context argument, and all functions to accept it (because in the general case you don't know when you call it whether it's a closure or an unclosed function). This is inappropriate to require in C for both technical and cultural reasons, so we're stuck with the option of either using explicit context pointers to fake a closure instead of nesting functions, or using a higher-level language that has the infrastructure needed to do it properly.
I'd like to quote something from the BDFL (Guido van Rossum):
This is because nested function definitions don't have access to the
local variables of the surrounding block -- only to the globals of the
containing module. This is done so that lookup of globals doesn't
have to walk a chain of dictionaries -- as in C, there are just two
nested scopes: locals and globals (and beyond this, built-ins).
Therefore, nested functions have only a limited use. This was a
deliberate decision, based upon experience with languages allowing
arbitraries nesting such as Pascal and both Algols -- code with too
many nested scopes is about as readable as code with too many GOTOs.
Emphasis is mine.
I believe he was referring to nested scope in Python (and as David points out in the comments, this was from 1993, and Python does support fully nested functions now) -- but I think the statement still applies.
The other part of it could have been closures.
If you have a function like this C-like code:
(*int()) foo() {
int x = 5;
int bar() {
x = x + 1;
return x;
}
return &bar;
}
If you use bar in a callback of some sort, what happens with x? This is well-defined in many newer, higher-level languages, but AFAIK there's no well-defined way to track that x in C -- does bar return 6 every time, or do successive calls to bar return incrementing values? That could have potentially added a whole new layer of complication to C's relatively simple definition.
See C FAQ 20.24 and the GCC manual for potential problems:
If you try to call the nested function
through its address after the
containing function has exited, all
hell will break loose. If you try to
call it after a containing scope level
has exited, and if it refers to some
of the variables that are no longer in
scope, you may be lucky, but it's not
wise to take the risk. If, however,
the nested function does not refer to
anything that has gone out of scope,
you should be safe.
This is not really more severe than some other problematic parts of the C standard, so I'd say the reasons are mostly historical (C99 isn't really that different from K&R C feature-wise).
There are some cases where nested functions with lexical scope might be useful (consider a recursive inner function which doesn't need extra stack space for the variables in the outer scope without the need for a static variable), but hopefully you can trust the compiler to correctly inline such functions, ie a solution with a seperate function will just be more verbose.
Nested functions are a very delicate thing. Will you make them closures? If not, then they have no advantage to regular functions, since they can't access any local variables. If they do, then what do you do to stack-allocated variables? You have to put them somewhere else so that if you call the nested function later, the variable is still there. This means they'll take memory, so you have to allocate room for them on the heap. With no GC, this means that the programmer is now in charge of cleaning up the functions. Etc... C# does this, but they have a GC, and it's a considerably newer language than C.
It also wouldn't be too hard to add members functions to structs but they are not in the standard either.
Features are not added to C standard based on soley whether or not they are easy to implement. It's a combination of many other factors including the point in time in which the standard was written and what was common / practical then.
One more reason: it is not at all clear that nested functions are valuable. Twenty-odd years ago I used to do large scale programming and maintenance in (VAX) Pascal. We had lots of old code that made heavy use of nested functions. At first, I thought this was way cool (compared to K&R C, which I had been working in before) and started doing it myself. After awhile, I decided it was a disaster, and stopped.
The problem was that a function could have a great many variables in scope, counting the variables of all the functions in which it was nested. (Some old code had ten levels of nesting; five was quite common, and until I changed my mind I coded a few of the latter myself.) Variables in the nesting stack could have the same names, so that "inner" function local variables could mask variables of the same name in more "outer" functions. A local variable of a function, that in C-like languages is totally private to it, could be modified by a call to a nested function. The set of possible combinations of this jazz was near infinite, and a nightmare to comprehend when reading code.
So, I started calling this programming construct "semi-global variables" instead of "nested functions", and telling other people working on the code that the only thing worse than a global variable was a semi-global variable, and please do not create any more. I would have banned it from the language, if I could. Sadly, there was no such option for the compiler...
ANSI C has been established for 20 years. Perhaps between 1983 and 1989 the committee may have discussed it in the light of the state of compiler technology at the time but if they did their reasoning is lost in dim and distant past.
I disagree with Dave Vandervies.
Defining a nested function is much better coding style than defining it in global scope, making it static and adding a comment saying "This is a helper function used only by myfunc()".
What if you needed a helper function for this helper function? Would you add a comment "This is a helper function for the first helper function used only by myfunc"? Where do you take the names from needed for all those functions without polluting the namespace completely?
How confusing can code be written?
But of course, there is the problem with how to deal with closuring, i.e. returning a pointer to a function that has access to variables defined in the function from which it is returned.
Either you don't allow references to local variables of the containing function in the contained one, and the nesting is just a scoping feature without much use, or you do. If you do, it is not a so simple feature: you have to be able to call a nested function from another one while accessing the correct data, and you also have to take into account recursive calls. That's not impossible -- techniques are well known for that and where well mastered when C was designed (Algol 60 had already the feature). But it complicates the run-time organization and the compiler and prevent a simple mapping to assembly language (a function pointer must carry on information about that; well there are alternatives such as the one gcc use). It was out of scope for the system implementation language C was designed to be.