Related
This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 2 years ago.
Hi i have a test code for calling malloc as below:
#include <stdio.h>
#include <stdlib.h>
int *p;// = (int*)malloc(sizeof(int));
int main() {
//...
}
Of course this code will be fail when compile with the error: initializer element is not constant and i have referenced this question: Malloc function (dynamic memory allocation) resulting in an error when it is used globally. They said that we have to use malloc() in side a function. But if i change my code to:
#include <stdio.h>
#include <stdlib.h>
int *p;
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
return x;
}
test_inline(p);
int main(){
//...
}
As the definition of inline function: "Inline Function are those function whose definitions are small and be substituted at the place where its function call is happened. Function substitution is totally compiler choice." So this mean we can substitute the inline function test_inline in above example with the code inside it and it means we have call malloc() in global ? Question 1: is this wrong about inline or malloc() ?
Question 2: In the link i give about malloc function dynamic there is an answer said that "Not only malloc, u can't call any function as you have called here. you can only declare function as global or local there" but i see that we still can call function in global and in global we can initialization not only declaration as below:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
So this mean in the global we still can declaration and initialization and call function. But when we compile the above code it has a warning that warning: data definition has no type or storage class So why we have this warning with variable b ? I do not see any thing which inconsequential here. And with the line test(); i have call a function outside main(), i know this make no sense because we never run test() but i have no problem, stil build success. So back to question 1 about the malloc(), i think with the answer that "we can not call a function in global or can not initialize", i think it is not true. Is there any explain more reasonable?
Please refer to the comments.
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1; //this is only allowed, because the previous line is a tentative definition. [1]
int test() {
printf("hello");
}
test(); // this is taken as a function declaration, not a function call [2]
int main() {
//...
}
Case [1]:
Change you code to
int b = 5; // not a tentative defintion.
b = 1; // this assignment is not valid in file scope.
you'll see an error.
Case [2]:
If the signature of the function differs, you'll again see an error. Example: try the below:
float test( int x ) {
printf("hello");
return 0.5;
} //return changed to float, accepts an int as paramater.
test(); //defaults to int and no parameter - conflict!!
this will produce the error for conflicting types.
So, bottom line, no assignment, function call - all in all, no code that needs to execute at runtime, can be put into file scope. The reason behind that being, unless it's contained in a function that's called from main(), there's no way to know when / how to execute it.
You're not calling functions "globally".
Taking your example:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
In C types default to int.
So the lines
int b;
b = 1;
are basically
int b;
int b = 1;
and the lines
int test() {
printf("hello");
}
test();
are just
int test() {
printf("hello");
}
int test(); // -> this is just a matching declaration
Have a look at:
https://godbolt.org/z/3UMQAr
(try changing int test() { ... to char test() { ... and you get a compiler error telling you that those types don't match)
That said, you can't call functions there. Functions are called at runtime by your program (especially malloc, which is asking your OS to allocate memory for you). I'm not a C expert here but as far as I know C doesn't have constexpr functions, which would be the only "exception".
See: Compile-Time Function Execution
Question 1: is this wrong about inline or malloc()
kind of: malloc does have to be called in a function, but the variable it works on can be declared global. i.e. int *pointer = NULL;//global scope
then pointer = malloc(someByteCount);//called within function. Now, pointer is still global, but also has a memory address pointing to someByteCount bytes of memory.
Question 2: In C, all functions are defined on the same level of a .c file, just like main(void){...return 0}, but all functions (except main(void)) must be called within the {...} of other functions, so in short, functions cannot be called from global space.
Illustration for Q2:
//prototypes
void func1(void);
void func2(void);
void func3(void);
int main(){
int val = test_inline(p);//...
}
int main(void)
{
//legal
func1();
func2();
func3();
return 0;
}
//not legal
func1();
func2();
func3();
//definitions
void func1(void)
{
return 0;
}
void func2(void)
{
return 0;
}
void func3(void)
{
return 0;
}
Errors in syntax of your example (see comments):
int *p = NULL;//initialize before use
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
printf("%p\n", x);
return 0;
//return x;//function returns int, not int *
}
//... test_inline(p);//must be called in a function
int main(void){
int val = test_inline(p);//function declaration returns int, not pointer
return 0;
}
This code compiles, and runs, but as noted in comments, usefulness may be lacking.
Question 1: is this wrong about inline or malloc() ?
Neither. Your understanding of inline is incorrect. The function call may be replaced with an inline expansion of the function definition. First, let's fix the function definition because the return type int doesn't match the type of what you're actually returning:
static inline int *test_inline( int *x )
{
printf( "in inline function\n" );
x = malloc( sizeof *x );
return x; // x has type int *, so the return type of the function needs to be int *
}
If you call this function like so:
int main( void )
{
int *foo = test_inline( foo );
...
}
what the compiler may do is substitute the function call with the assembly language equivalent of the following:
int main( void )
{
int *foo;
do
{
printf( "in inline function\n" );
int *x = malloc( sizeof *x );
foo = x;
} while( 0 );
...
}
Nothing's happening "globally" here. The substitution is at the point of execution (within the body of the main function), not at the point of definition.
Question 2: In the link i give about malloc function dynamic there is an answer said that "Not only malloc, u can't call any function as you have called here. you can only declare function as global or local there" but i see that we still can call function in global and in global we can initialization not only declaration as below:
In the code
int test() {
printf("hello");
}
test();
the line test(); is not a function call - it's a (redundant and unnecessary) declaration. It does not execute the function.
Here are some excerpts from the language definition to clarify some of this:
6.2.4 Storage durations of objects
...
3 An object whose identifier is declared without the storage-class specifier
_Thread_local, and either with external or internal linkage or with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.
Bold added. Any variable declared outside the body of a function (such as p in your first code snippet) has static storage duration. Since such objects are initialized before runtime, they cannot be initialized with a runtime value (such as the result of a function call).
6.7.4 Function specifiers
...
6 A function declared with an inline function specifier is an inline function. Making a
function an inline function suggests that calls to the function be as fast as possible.138)
The extent to which such suggestions are effective is implementation-defined.139)
138) By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline
substitution’’. Inline substitution is not textual substitution, nor does it create a new function.
Therefore, for example, the expansion of a macro used within the body of the function uses the
definition it had at the point the function body appears, and not where the function is called; and
identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a
single address, regardless of the number of inline definitions that occur in addition to the external
definition.
139) For example, an implementation might never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration
All this means is that the inlined code behaves like it was still a single function definition, even if it's expanded in multiple places throughout the program.
I accidentally forgot to add (int) when defining a function pointer, and my program still worked.
I wold like to know if there is any case where it would not work.
my code:
#include <stdio.h>
void f1(int var)
{
printf("this is f1 and var is: %d\n", var);
}
void f2(int var)
{
printf("this is f2 and var is: %d\n", var);
}
void f3(int var)
{
printf("this is f3 and var is: %d\n", var);
}
typedef void (*f_ptr)(int);
// pq eu poderia escrever: typedef void (*f_ptr)(); e o programa funcionaria normalmente?
typedef int n_casa;
int main()
{
f_ptr ptr[] = {f1, f2, f3};
int c = 0;
while (c < 3)
{
ptr[c](c);
++c;
}
return 0;
}
both typedef void (*f_ptr)(int); and typedef void (*f_ptr)(); worked in my program.
They are different.
typedef void (*f_ptr)(int) declares a funciton pointer that takes only one int argument, and returns nothing.
While for typedef void (*f_ptr)(), the function pointer takes an UNSPECIFIED number of arguments, and returns nothing.
According to the SEI CERT C Coding Standard, it is recommended to explicitly specify void when a function accepts no arguments.
From my little assembly experience: When you call a function with an argument, it pushes the argument onto the stack and then executes the function. Then the function reads the arguments from the top of the stack.
If you call f_ptr with no arguments, you won't get an error, you'll just get a garbage value in var. If you call it with 100 arguments, you'll just get the first one.
I think the only reason the compiler doesn't stop you is that it isn't smart enough to.
I had some experience lately with function pointers in C.
So going on with the tradition of answering your own questions, I decided to make a small summary of the very basics, for those who need a quick dive-in to the subject.
Function pointers in C
Let's start with a basic function which we will be pointing to:
int addInt(int n, int m) {
return n+m;
}
First thing, let's define a pointer to a function which receives 2 ints and returns an int:
int (*functionPtr)(int,int);
Now we can safely point to our function:
functionPtr = &addInt;
Now that we have a pointer to the function, let's use it:
int sum = (*functionPtr)(2, 3); // sum == 5
Passing the pointer to another function is basically the same:
int add2to3(int (*functionPtr)(int, int)) {
return (*functionPtr)(2, 3);
}
We can use function pointers in return values as well (try to keep up, it gets messy):
// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
printf("Got parameter %d", n);
int (*functionPtr)(int,int) = &addInt;
return functionPtr;
}
But it's much nicer to use a typedef:
typedef int (*myFuncDef)(int, int);
// note that the typedef name is indeed myFuncDef
myFuncDef functionFactory(int n) {
printf("Got parameter %d", n);
myFuncDef functionPtr = &addInt;
return functionPtr;
}
Function pointers in C can be used to perform object-oriented programming in C.
For example, the following lines is written in C:
String s1 = newString();
s1->set(s1, "hello");
Yes, the -> and the lack of a new operator is a dead give away, but it sure seems to imply that we're setting the text of some String class to be "hello".
By using function pointers, it is possible to emulate methods in C.
How is this accomplished?
The String class is actually a struct with a bunch of function pointers which act as a way to simulate methods. The following is a partial declaration of the String class:
typedef struct String_Struct* String;
struct String_Struct
{
char* (*get)(const void* self);
void (*set)(const void* self, char* value);
int (*length)(const void* self);
};
char* getString(const void* self);
void setString(const void* self, char* value);
int lengthString(const void* self);
String newString();
As can be seen, the methods of the String class are actually function pointers to the declared function. In preparing the instance of the String, the newString function is called in order to set up the function pointers to their respective functions:
String newString()
{
String self = (String)malloc(sizeof(struct String_Struct));
self->get = &getString;
self->set = &setString;
self->length = &lengthString;
self->set(self, "");
return self;
}
For example, the getString function that is called by invoking the get method is defined as the following:
char* getString(const void* self_obj)
{
return ((String)self_obj)->internal->value;
}
One thing that can be noticed is that there is no concept of an instance of an object and having methods that are actually a part of an object, so a "self object" must be passed in on each invocation. (And the internal is just a hidden struct which was omitted from the code listing earlier -- it is a way of performing information hiding, but that is not relevant to function pointers.)
So, rather than being able to do s1->set("hello");, one must pass in the object to perform the action on s1->set(s1, "hello").
With that minor explanation having to pass in a reference to yourself out of the way, we'll move to the next part, which is inheritance in C.
Let's say we want to make a subclass of String, say an ImmutableString. In order to make the string immutable, the set method will not be accessible, while maintaining access to get and length, and force the "constructor" to accept a char*:
typedef struct ImmutableString_Struct* ImmutableString;
struct ImmutableString_Struct
{
String base;
char* (*get)(const void* self);
int (*length)(const void* self);
};
ImmutableString newImmutableString(const char* value);
Basically, for all subclasses, the available methods are once again function pointers. This time, the declaration for the set method is not present, therefore, it cannot be called in a ImmutableString.
As for the implementation of the ImmutableString, the only relevant code is the "constructor" function, the newImmutableString:
ImmutableString newImmutableString(const char* value)
{
ImmutableString self = (ImmutableString)malloc(sizeof(struct ImmutableString_Struct));
self->base = newString();
self->get = self->base->get;
self->length = self->base->length;
self->base->set(self->base, (char*)value);
return self;
}
In instantiating the ImmutableString, the function pointers to the get and length methods actually refer to the String.get and String.length method, by going through the base variable which is an internally stored String object.
The use of a function pointer can achieve inheritance of a method from a superclass.
We can further continue to polymorphism in C.
If for example we wanted to change the behavior of the length method to return 0 all the time in the ImmutableString class for some reason, all that would have to be done is to:
Add a function that is going to serve as the overriding length method.
Go to the "constructor" and set the function pointer to the overriding length method.
Adding an overriding length method in ImmutableString may be performed by adding an lengthOverrideMethod:
int lengthOverrideMethod(const void* self)
{
return 0;
}
Then, the function pointer for the length method in the constructor is hooked up to the lengthOverrideMethod:
ImmutableString newImmutableString(const char* value)
{
ImmutableString self = (ImmutableString)malloc(sizeof(struct ImmutableString_Struct));
self->base = newString();
self->get = self->base->get;
self->length = &lengthOverrideMethod;
self->base->set(self->base, (char*)value);
return self;
}
Now, rather than having an identical behavior for the length method in ImmutableString class as the String class, now the length method will refer to the behavior defined in the lengthOverrideMethod function.
I must add a disclaimer that I am still learning how to write with an object-oriented programming style in C, so there probably are points that I didn't explain well, or may just be off mark in terms of how best to implement OOP in C. But my purpose was to try to illustrate one of many uses of function pointers.
For more information on how to perform object-oriented programming in C, please refer to the following questions:
Object-Orientation in C?
Can you write object oriented code in C?
The guide to getting fired: How to abuse function pointers in GCC on x86 machines by compiling your code by hand:
These string literals are bytes of 32-bit x86 machine code. 0xC3 is an x86 ret instruction.
You wouldn't normally write these by hand, you'd write in assembly language and then use an assembler like nasm to assemble it into a flat binary which you hexdump into a C string literal.
Returns the current value on the EAX register
int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))();
Write a swap function
int a = 10, b = 20;
((void(*)(int*,int*))"\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3 <- This swaps the values of a and b")(&a,&b);
Write a for-loop counter to 1000, calling some function each time
((int(*)())"\x66\x31\xc0\x8b\x5c\x24\x04\x66\x40\x50\xff\xd3\x58\x66\x3d\xe8\x03\x75\xf4\xc3")(&function); // calls function with 1->1000
You can even write a recursive function that counts to 100
const char* lol = "\x8b\x5c\x24\x4\x3d\xe8\x3\x0\x0\x7e\x2\x31\xc0\x83\xf8\x64\x7d\x6\x40\x53\xff\xd3\x5b\xc3\xc3 <- Recursively calls the function at address lol.";
i = ((int(*)())(lol))(lol);
Note that compilers place string literals in the .rodata section (or .rdata on Windows), which is linked as part of the text segment (along with code for functions).
The text segment has Read+Exec permission, so casting string literals to function pointers works without needing mprotect() or VirtualProtect() system calls like you'd need for dynamically allocated memory. (Or gcc -z execstack links the program with stack + data segment + heap executable, as a quick hack.)
To disassemble these, you can compile this to put a label on the bytes, and use a disassembler.
// at global scope
const char swap[] = "\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3 <- This swaps the values of a and b";
Compiling with gcc -c -m32 foo.c and disassembling with objdump -D -rwC -Mintel, we can get the assembly, and find out that this code violates the ABI by clobbering EBX (a call-preserved register) and is generally inefficient.
00000000 <swap>:
0: 8b 44 24 04 mov eax,DWORD PTR [esp+0x4] # load int *a arg from the stack
4: 8b 5c 24 08 mov ebx,DWORD PTR [esp+0x8] # ebx = b
8: 8b 00 mov eax,DWORD PTR [eax] # dereference: eax = *a
a: 8b 1b mov ebx,DWORD PTR [ebx]
c: 31 c3 xor ebx,eax # pointless xor-swap
e: 31 d8 xor eax,ebx # instead of just storing with opposite registers
10: 31 c3 xor ebx,eax
12: 8b 4c 24 04 mov ecx,DWORD PTR [esp+0x4] # reload a from the stack
16: 89 01 mov DWORD PTR [ecx],eax # store to *a
18: 8b 4c 24 08 mov ecx,DWORD PTR [esp+0x8]
1c: 89 19 mov DWORD PTR [ecx],ebx
1e: c3 ret
not shown: the later bytes are ASCII text documentation
they're not executed by the CPU because the ret instruction sends execution back to the caller
This machine code will (probably) work in 32-bit code on Windows, Linux, OS X, and so on: the default calling conventions on all those OSes pass args on the stack instead of more efficiently in registers. But EBX is call-preserved in all the normal calling conventions, so using it as a scratch register without saving/restoring it can easily make the caller crash.
One of my favorite uses for function pointers is as cheap and easy iterators -
#include <stdio.h>
#define MAX_COLORS 256
typedef struct {
char* name;
int red;
int green;
int blue;
} Color;
Color Colors[MAX_COLORS];
void eachColor (void (*fp)(Color *c)) {
int i;
for (i=0; i<MAX_COLORS; i++)
(*fp)(&Colors[i]);
}
void printColor(Color* c) {
if (c->name)
printf("%s = %i,%i,%i\n", c->name, c->red, c->green, c->blue);
}
int main() {
Colors[0].name="red";
Colors[0].red=255;
Colors[1].name="blue";
Colors[1].blue=255;
Colors[2].name="black";
eachColor(printColor);
}
Function pointers become easy to declare once you have the basic declarators:
id: ID: ID is a
Pointer: *D: D pointer to
Function: D(<parameters>): D function taking <parameters> returning
While D is another declarator built using those same rules. In the end, somewhere, it ends with ID (see below for an example), which is the name of the declared entity. Let's try to build a function taking a pointer to a function taking nothing and returning int, and returning a pointer to a function taking a char and returning int. With type-defs it's like this
typedef int ReturnFunction(char);
typedef int ParameterFunction(void);
ReturnFunction *f(ParameterFunction *p);
As you see, it's pretty easy to build it up using typedefs. Without typedefs, it's not hard either with the above declarator rules, applied consistently. As you see i missed out the part the pointer points to, and the thing the function returns. That's what appears at the very left of the declaration, and is not of interest: It's added at the end if one built up the declarator already. Let's do that. Building it up consistently, first wordy - showing the structure using [ and ]:
function taking
[pointer to [function taking [void] returning [int]]]
returning
[pointer to [function taking [char] returning [int]]]
As you see, one can describe a type completely by appending declarators one after each other. Construction can be done in two ways. One is bottom-up, starting with the very right thing (leaves) and working the way through up to the identifier. The other way is top-down, starting at the identifier, working the way down to the leaves. I'll show both ways.
Bottom Up
Construction starts with the thing at the right: The thing returned, which is the function taking char. To keep the declarators distinct, i'm going to number them:
D1(char);
Inserted the char parameter directly, since it's trivial. Adding a pointer to declarator by replacing D1 by *D2. Note that we have to wrap parentheses around *D2. That can be known by looking up the precedence of the *-operator and the function-call operator (). Without our parentheses, the compiler would read it as *(D2(char p)). But that would not be a plain replace of D1 by *D2 anymore, of course. Parentheses are always allowed around declarators. So you don't make anything wrong if you add too much of them, actually.
(*D2)(char);
Return type is complete! Now, let's replace D2 by the function declarator function taking <parameters> returning, which is D3(<parameters>) which we are at now.
(*D3(<parameters>))(char)
Note that no parentheses are needed, since we want D3 to be a function-declarator and not a pointer declarator this time. Great, only thing left is the parameters for it. The parameter is done exactly the same as we've done the return type, just with char replaced by void. So i'll copy it:
(*D3( (*ID1)(void)))(char)
I've replaced D2 by ID1, since we are finished with that parameter (it's already a pointer to a function - no need for another declarator). ID1 will be the name of the parameter. Now, i told above at the end one adds the type which all those declarator modify - the one appearing at the very left of every declaration. For functions, that becomes the return type. For pointers the pointed to type etc... It's interesting when written down the type, it will appear in the opposite order, at the very right :) Anyway, substituting it yields the complete declaration. Both times int of course.
int (*ID0(int (*ID1)(void)))(char)
I've called the identifier of the function ID0 in that example.
Top Down
This starts at the identifier at the very left in the description of the type, wrapping that declarator as we walk our way through the right. Start with function taking <parameters> returning
ID0(<parameters>)
The next thing in the description (after "returning") was pointer to. Let's incorporate it:
*ID0(<parameters>)
Then the next thing was functon taking <parameters> returning. The parameter is a simple char, so we put it in right away again, since it's really trivial.
(*ID0(<parameters>))(char)
Note the parentheses we added, since we again want that the * binds first, and then the (char). Otherwise it would read function taking <parameters> returning function .... Noes, functions returning functions aren't even allowed.
Now we just need to put <parameters>. I will show a short version of the deriveration, since i think you already by now have the idea how to do it.
pointer to: *ID1
... function taking void returning: (*ID1)(void)
Just put int before the declarators like we did with bottom-up, and we are finished
int (*ID0(int (*ID1)(void)))(char)
The nice thing
Is bottom-up or top-down better? I'm used to bottom-up, but some people may be more comfortable with top-down. It's a matter of taste i think. Incidentally, if you apply all the operators in that declaration, you will end up getting an int:
int v = (*ID0(some_function_pointer))(some_char);
That is a nice property of declarations in C: The declaration asserts that if those operators are used in an expression using the identifier, then it yields the type on the very left. It's like that for arrays too.
Hope you liked this little tutorial! Now we can link to this when people wonder about the strange declaration syntax of functions. I tried to put as little C internals as possible. Feel free to edit/fix things in it.
Another good use for function pointers:Switching between versions painlessly
They're very handy to use for when you want different functions at different times, or different phases of development. For instance, I'm developing an application on a host computer that has a console, but the final release of the software will be put on an Avnet ZedBoard (which has ports for displays and consoles, but they are not needed/wanted for the final release). So during development, I will use printf to view status and error messages, but when I'm done, I don't want anything printed. Here's what I've done:
version.h
// First, undefine all macros associated with version.h
#undef DEBUG_VERSION
#undef RELEASE_VERSION
#undef INVALID_VERSION
// Define which version we want to use
#define DEBUG_VERSION // The current version
// #define RELEASE_VERSION // To be uncommented when finished debugging
#ifndef __VERSION_H_ /* prevent circular inclusions */
#define __VERSION_H_ /* by using protection macros */
void board_init();
void noprintf(const char *c, ...); // mimic the printf prototype
#endif
// Mimics the printf function prototype. This is what I'll actually
// use to print stuff to the screen
void (* zprintf)(const char*, ...);
// If debug version, use printf
#ifdef DEBUG_VERSION
#include <stdio.h>
#endif
// If both debug and release version, error
#ifdef DEBUG_VERSION
#ifdef RELEASE_VERSION
#define INVALID_VERSION
#endif
#endif
// If neither debug or release version, error
#ifndef DEBUG_VERSION
#ifndef RELEASE_VERSION
#define INVALID_VERSION
#endif
#endif
#ifdef INVALID_VERSION
// Won't allow compilation without a valid version define
#error "Invalid version definition"
#endif
In version.c I will define the 2 function prototypes present in version.h
version.c
#include "version.h"
/*****************************************************************************/
/**
* #name board_init
*
* Sets up the application based on the version type defined in version.h.
* Includes allowing or prohibiting printing to STDOUT.
*
* MUST BE CALLED FIRST THING IN MAIN
*
* #return None
*
*****************************************************************************/
void board_init()
{
// Assign the print function to the correct function pointer
#ifdef DEBUG_VERSION
zprintf = &printf;
#else
// Defined below this function
zprintf = &noprintf;
#endif
}
/*****************************************************************************/
/**
* #name noprintf
*
* simply returns with no actions performed
*
* #return None
*
*****************************************************************************/
void noprintf(const char* c, ...)
{
return;
}
Notice how the function pointer is prototyped in version.h as void (* zprintf)(const char *, ...);When it is referenced in the application, it will start executing wherever it is pointing, which has yet to be defined.
In version.c, notice in the board_init()function where zprintf is assigned a unique function (whose function signature matches) depending on the version that is defined in version.hzprintf = &printf; zprintf calls printf for debugging purposesorzprintf = &noprint; zprintf just returns and will not run unnecessary code
Running the code will look like this:
mainProg.c
#include "version.h"
#include <stdlib.h>
int main()
{
// Must run board_init(), which assigns the function
// pointer to an actual function
board_init();
void *ptr = malloc(100); // Allocate 100 bytes of memory
// malloc returns NULL if unable to allocate the memory.
if (ptr == NULL)
{
zprintf("Unable to allocate memory\n");
return 1;
}
// Other things to do...
return 0;
}
The above code will use printf if in debug mode, or do nothing if in release mode. This is much easier than going through the entire project and commenting out or deleting code. All that I need to do is change the version in version.h and the code will do the rest!
Function pointer is usually defined by typedef, and used as param & return value.
Above answers already explained a lot, I just give a full example:
#include <stdio.h>
#define NUM_A 1
#define NUM_B 2
// define a function pointer type
typedef int (*two_num_operation)(int, int);
// an actual standalone function
static int sum(int a, int b) {
return a + b;
}
// use function pointer as param,
static int sum_via_pointer(int a, int b, two_num_operation funp) {
return (*funp)(a, b);
}
// use function pointer as return value,
static two_num_operation get_sum_fun() {
return ∑
}
// test - use function pointer as variable,
void test_pointer_as_variable() {
// create a pointer to function,
two_num_operation sum_p = ∑
// call function via pointer
printf("pointer as variable:\t %d + %d = %d\n", NUM_A, NUM_B, (*sum_p)(NUM_A, NUM_B));
}
// test - use function pointer as param,
void test_pointer_as_param() {
printf("pointer as param:\t %d + %d = %d\n", NUM_A, NUM_B, sum_via_pointer(NUM_A, NUM_B, &sum));
}
// test - use function pointer as return value,
void test_pointer_as_return_value() {
printf("pointer as return value:\t %d + %d = %d\n", NUM_A, NUM_B, (*get_sum_fun())(NUM_A, NUM_B));
}
int main() {
test_pointer_as_variable();
test_pointer_as_param();
test_pointer_as_return_value();
return 0;
}
A function pointer is a variable that contains the address of a function. Since it is a pointer variable though with some restricted properties, you can use it pretty much like you would any other pointer variable in data structures.
The only exception I can think of is treating the function pointer as pointing to something other than a single value. Doing pointer arithmetic by incrementing or decrementing a function pointer or adding/subtracting an offset to a function pointer isn't really of any utility as a function pointer only points to a single thing, the entry point of a function.
The size of a function pointer variable, the number of bytes occupied by the variable, may vary depending on the underlying architecture, e.g. x32 or x64 or whatever.
The declaration for a function pointer variable needs to specify the same kind of information as a function declaration in order for the C compiler to do the kinds of checks that it normally does. If you don't specify a parameter list in the declaration/definition of the function pointer, the C compiler will not be able to check the use of parameters. There are cases when this lack of checking can be useful however just remember that a safety net has been removed.
Some examples:
int func (int a, char *pStr); // declares a function
int (*pFunc)(int a, char *pStr); // declares or defines a function pointer
int (*pFunc2) (); // declares or defines a function pointer, no parameter list specified.
int (*pFunc3) (void); // declares or defines a function pointer, no arguments.
The first two declararations are somewhat similar in that:
func is a function that takes an int and a char * and returns an int
pFunc is a function pointer to which is assigned the address of a function that takes an int and a char * and returns an int
So from the above we could have a source line in which the address of the function func() is assigned to the function pointer variable pFunc as in pFunc = func;.
Notice the syntax used with a function pointer declaration/definition in which parenthesis are used to overcome the natural operator precedence rules.
int *pfunc(int a, char *pStr); // declares a function that returns int pointer
int (*pFunc)(int a, char *pStr); // declares a function pointer that returns an int
Several Different Usage Examples
Some examples of usage of a function pointer:
int (*pFunc) (int a, char *pStr); // declare a simple function pointer variable
int (*pFunc[55])(int a, char *pStr); // declare an array of 55 function pointers
int (**pFunc)(int a, char *pStr); // declare a pointer to a function pointer variable
struct { // declare a struct that contains a function pointer
int x22;
int (*pFunc)(int a, char *pStr);
} thing = {0, func}; // assign values to the struct variable
char * xF (int x, int (*p)(int a, char *pStr)); // declare a function that has a function pointer as an argument
char * (*pxF) (int x, int (*p)(int a, char *pStr)); // declare a function pointer that points to a function that has a function pointer as an argument
You can use variable length parameter lists in the definition of a function pointer.
int sum (int a, int b, ...);
int (*psum)(int a, int b, ...);
Or you can not specify a parameter list at all. This can be useful but it eliminates the opportunity for the C compiler to perform checks on the argument list provided.
int sum (); // nothing specified in the argument list so could be anything or nothing
int (*psum)();
int sum2(void); // void specified in the argument list so no parameters when calling this function
int (*psum2)(void);
C style Casts
You can use C style casts with function pointers. However be aware that a C compiler may be lax about checks or provide warnings rather than errors.
int sum (int a, char *b);
int (*psplsum) (int a, int b);
psplsum = sum; // generates a compiler warning
psplsum = (int (*)(int a, int b)) sum; // no compiler warning, cast to function pointer
psplsum = (int *(int a, int b)) sum; // compiler error of bad cast generated, parenthesis are required.
Compare Function Pointer to Equality
You can check that a function pointer is equal to a particular function address using an if statement though I am not sure how useful that would be. Other comparison operators would seem to have even less utility.
static int func1(int a, int b) {
return a + b;
}
static int func2(int a, int b, char *c) {
return c[0] + a + b;
}
static int func3(int a, int b, char *x) {
return a + b;
}
static char *func4(int a, int b, char *c, int (*p)())
{
if (p == func1) {
p(a, b);
}
else if (p == func2) {
p(a, b, c); // warning C4047: '==': 'int (__cdecl *)()' differs in levels of indirection from 'char *(__cdecl *)(int,int,char *)'
} else if (p == func3) {
p(a, b, c);
}
return c;
}
An Array of Function Pointers
And if you want to have an array of function pointers each of the elements of which the argument list has differences then you can define a function pointer with the argument list unspecified (not void which means no arguments but just unspecified) something like the following though you may see warnings from the C compiler. This also works for a function pointer parameter to a function:
int(*p[])() = { // an array of function pointers
func1, func2, func3
};
int(**pp)(); // a pointer to a function pointer
p[0](a, b);
p[1](a, b, 0);
p[2](a, b); // oops, left off the last argument but it compiles anyway.
func4(a, b, 0, func1);
func4(a, b, 0, func2); // warning C4047: 'function': 'int (__cdecl *)()' differs in levels of indirection from 'char *(__cdecl *)(int,int,char *)'
func4(a, b, 0, func3);
// iterate over the array elements using an array index
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
func4(a, b, 0, p[i]);
}
// iterate over the array elements using a pointer
for (pp = p; pp < p + sizeof(p)/sizeof(p[0]); pp++) {
(*pp)(a, b, 0); // pointer to a function pointer so must dereference it.
func4(a, b, 0, *pp); // pointer to a function pointer so must dereference it.
}
C style namespace Using Global struct with Function Pointers
You can use the static keyword to specify a function whose name is file scope and then assign this to a global variable as a way of providing something similar to the namespace functionality of C++.
In a header file define a struct that will be our namespace along with a global variable that uses it.
typedef struct {
int (*func1) (int a, int b); // pointer to function that returns an int
char *(*func2) (int a, int b, char *c); // pointer to function that returns a pointer
} FuncThings;
extern const FuncThings FuncThingsGlobal;
Then in the C source file:
#include "header.h"
// the function names used with these static functions do not need to be the
// same as the struct member names. It's just helpful if they are when trying
// to search for them.
// the static keyword ensures these names are file scope only and not visible
// outside of the file.
static int func1 (int a, int b)
{
return a + b;
}
static char *func2 (int a, int b, char *c)
{
c[0] = a % 100; c[1] = b % 50;
return c;
}
const FuncThings FuncThingsGlobal = {func1, func2};
This would then be used by specifying the complete name of global struct variable and member name to access the function. The const modifier is used on the global so that it can not be changed by accident.
int abcd = FuncThingsGlobal.func1 (a, b);
Application Areas of Function Pointers
A DLL library component could do something similar to the C style namespace approach in which a particular library interface is requested from a factory method in a library interface which supports the creation of a struct containing function pointers.. This library interface loads the requested DLL version, creates a struct with the necessary function pointers, and then returns the struct to the requesting caller for use.
typedef struct {
HMODULE hModule;
int (*Func1)();
int (*Func2)();
int(*Func3)(int a, int b);
} LibraryFuncStruct;
int LoadLibraryFunc LPCTSTR dllFileName, LibraryFuncStruct *pStruct)
{
int retStatus = 0; // default is an error detected
pStruct->hModule = LoadLibrary (dllFileName);
if (pStruct->hModule) {
pStruct->Func1 = (int (*)()) GetProcAddress (pStruct->hModule, "Func1");
pStruct->Func2 = (int (*)()) GetProcAddress (pStruct->hModule, "Func2");
pStruct->Func3 = (int (*)(int a, int b)) GetProcAddress(pStruct->hModule, "Func3");
retStatus = 1;
}
return retStatus;
}
void FreeLibraryFunc (LibraryFuncStruct *pStruct)
{
if (pStruct->hModule) FreeLibrary (pStruct->hModule);
pStruct->hModule = 0;
}
and this could be used as in:
LibraryFuncStruct myLib = {0};
LoadLibraryFunc (L"library.dll", &myLib);
// ....
myLib.Func1();
// ....
FreeLibraryFunc (&myLib);
The same approach can be used to define an abstract hardware layer for code that uses a particular model of the underlying hardware. Function pointers are filled in with hardware specific functions by a factory to provide the hardware specific functionality that implements functions specified in the abstract hardware model. This can be used to provide an abstract hardware layer used by software which calls a factory function in order to get the specific hardware function interface then uses the function pointers provided to perform actions for the underlying hardware without needing to know implementation details about the specific target.
Function Pointers to create Delegates, Handlers, and Callbacks
You can use function pointers as a way to delegate some task or functionality. The classic example in C is the comparison delegate function pointer used with the Standard C library functions qsort() and bsearch() to provide the collation order for sorting a list of items or performing a binary search over a sorted list of items. The comparison function delegate specifies the collation algorithm used in the sort or the binary search.
Another use is similar to applying an algorithm to a C++ Standard Template Library container.
void * ApplyAlgorithm (void *pArray, size_t sizeItem, size_t nItems, int (*p)(void *)) {
unsigned char *pList = pArray;
unsigned char *pListEnd = pList + nItems * sizeItem;
for ( ; pList < pListEnd; pList += sizeItem) {
p (pList);
}
return pArray;
}
int pIncrement(int *pI) {
(*pI)++;
return 1;
}
void * ApplyFold(void *pArray, size_t sizeItem, size_t nItems, void * pResult, int(*p)(void *, void *)) {
unsigned char *pList = pArray;
unsigned char *pListEnd = pList + nItems * sizeItem;
for (; pList < pListEnd; pList += sizeItem) {
p(pList, pResult);
}
return pArray;
}
int pSummation(int *pI, int *pSum) {
(*pSum) += *pI;
return 1;
}
// source code and then lets use our function.
int intList[30] = { 0 }, iSum = 0;
ApplyAlgorithm(intList, sizeof(int), sizeof(intList) / sizeof(intList[0]), pIncrement);
ApplyFold(intList, sizeof(int), sizeof(intList) / sizeof(intList[0]), &iSum, pSummation);
Another example is with GUI source code in which a handler for a particular event is registered by providing a function pointer which is actually called when the event happens. The Microsoft MFC framework with its message maps uses something similar to handle Windows messages that are delivered to a window or thread.
Asynchronous functions that require a callback are similar to an event handler. The user of the asynchronous function calls the asynchronous function to start some action and provides a function pointer which the asynchronous function will call once the action is complete. In this case the event is the asynchronous function completing its task.
Starting from scratch function has Some Memory Address From Where They start executing. In Assembly Language They Are called as (call "function's memory address").Now come back to C If function has a memory address then they can be manipulated by Pointers in C.So By the rules of C
1.First you need to declare a pointer to function
2.Pass the Address of the Desired function
****Note->the functions should be of same type****
This Simple Programme will Illustrate Every Thing.
#include<stdio.h>
void (*print)() ;//Declare a Function Pointers
void sayhello();//Declare The Function Whose Address is to be passed
//The Functions should Be of Same Type
int main()
{
print=sayhello;//Addressof sayhello is assigned to print
print();//print Does A call To The Function
return 0;
}
void sayhello()
{
printf("\n Hello World");
}
After That lets See How machine Understands Them.Glimpse of machine instruction of the above programme in 32 bit architecture.
The red mark area is showing how the address is being exchanged and storing in eax. Then their is a call instruction on eax. eax contains the desired address of the function.
One of the big uses for function pointers in C is to call a function selected at run-time. For example, the C run-time library has two routines, qsort and bsearch, which take a pointer to a function that is called to compare two items being sorted; this allows you to sort or search, respectively, anything, based on any criteria you wish to use.
A very basic example, if there is one function called print(int x, int y) which in turn may require to call a function (either add() or sub(), which are of the same type) then what we will do, we will add one function pointer argument to the print() function as shown below:
#include <stdio.h>
int add()
{
return (100+10);
}
int sub()
{
return (100-10);
}
void print(int x, int y, int (*func)())
{
printf("value is: %d\n", (x+y+(*func)()));
}
int main()
{
int x=100, y=200;
print(x,y,add);
print(x,y,sub);
return 0;
}
The output is:
value is: 410
value is: 390
Since function pointers are often typed callbacks, you might want to have a look at type safe callbacks. The same applies to entry points, etc of functions that are not callbacks.
C is quite fickle and forgiving at the same time :)
Pointers to functions are useful because, as "The C Programming Language" book says, functions in C are not variables.
This means,
// Say you have add function
int add(int x, int y){
return x + y;
}
// Say you have another add function
int another_add(int x, int y){
return y + x;
}
int main(){
// Although the types of another_add and add are same
// You can't do
another_add = add
// You have a compute function that takes a function of int's signature
int (*compute)(int, int);
// You won't even be able to pass functions to other functions
// (Although when you do, C is just passing the pointer to that function)
// So, compute(add) is really compute(&add)
// But you can create a pointer to functions that are variables
// you can assign to and/or pass to other functions
int (*operation)(int, int);
// Now you can do
operation = &add;
// You could also do, the following to do the same thing
// When a function is passed in right hand side of assignment,
// C knows that you mean pointer, and you don't need explicit &
operation = add;
}
Similarly, an array is also not a variable in C. You can make up a similar example as above and test out.
I had some experience lately with function pointers in C.
So going on with the tradition of answering your own questions, I decided to make a small summary of the very basics, for those who need a quick dive-in to the subject.
Function pointers in C
Let's start with a basic function which we will be pointing to:
int addInt(int n, int m) {
return n+m;
}
First thing, let's define a pointer to a function which receives 2 ints and returns an int:
int (*functionPtr)(int,int);
Now we can safely point to our function:
functionPtr = &addInt;
Now that we have a pointer to the function, let's use it:
int sum = (*functionPtr)(2, 3); // sum == 5
Passing the pointer to another function is basically the same:
int add2to3(int (*functionPtr)(int, int)) {
return (*functionPtr)(2, 3);
}
We can use function pointers in return values as well (try to keep up, it gets messy):
// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
printf("Got parameter %d", n);
int (*functionPtr)(int,int) = &addInt;
return functionPtr;
}
But it's much nicer to use a typedef:
typedef int (*myFuncDef)(int, int);
// note that the typedef name is indeed myFuncDef
myFuncDef functionFactory(int n) {
printf("Got parameter %d", n);
myFuncDef functionPtr = &addInt;
return functionPtr;
}
Function pointers in C can be used to perform object-oriented programming in C.
For example, the following lines is written in C:
String s1 = newString();
s1->set(s1, "hello");
Yes, the -> and the lack of a new operator is a dead give away, but it sure seems to imply that we're setting the text of some String class to be "hello".
By using function pointers, it is possible to emulate methods in C.
How is this accomplished?
The String class is actually a struct with a bunch of function pointers which act as a way to simulate methods. The following is a partial declaration of the String class:
typedef struct String_Struct* String;
struct String_Struct
{
char* (*get)(const void* self);
void (*set)(const void* self, char* value);
int (*length)(const void* self);
};
char* getString(const void* self);
void setString(const void* self, char* value);
int lengthString(const void* self);
String newString();
As can be seen, the methods of the String class are actually function pointers to the declared function. In preparing the instance of the String, the newString function is called in order to set up the function pointers to their respective functions:
String newString()
{
String self = (String)malloc(sizeof(struct String_Struct));
self->get = &getString;
self->set = &setString;
self->length = &lengthString;
self->set(self, "");
return self;
}
For example, the getString function that is called by invoking the get method is defined as the following:
char* getString(const void* self_obj)
{
return ((String)self_obj)->internal->value;
}
One thing that can be noticed is that there is no concept of an instance of an object and having methods that are actually a part of an object, so a "self object" must be passed in on each invocation. (And the internal is just a hidden struct which was omitted from the code listing earlier -- it is a way of performing information hiding, but that is not relevant to function pointers.)
So, rather than being able to do s1->set("hello");, one must pass in the object to perform the action on s1->set(s1, "hello").
With that minor explanation having to pass in a reference to yourself out of the way, we'll move to the next part, which is inheritance in C.
Let's say we want to make a subclass of String, say an ImmutableString. In order to make the string immutable, the set method will not be accessible, while maintaining access to get and length, and force the "constructor" to accept a char*:
typedef struct ImmutableString_Struct* ImmutableString;
struct ImmutableString_Struct
{
String base;
char* (*get)(const void* self);
int (*length)(const void* self);
};
ImmutableString newImmutableString(const char* value);
Basically, for all subclasses, the available methods are once again function pointers. This time, the declaration for the set method is not present, therefore, it cannot be called in a ImmutableString.
As for the implementation of the ImmutableString, the only relevant code is the "constructor" function, the newImmutableString:
ImmutableString newImmutableString(const char* value)
{
ImmutableString self = (ImmutableString)malloc(sizeof(struct ImmutableString_Struct));
self->base = newString();
self->get = self->base->get;
self->length = self->base->length;
self->base->set(self->base, (char*)value);
return self;
}
In instantiating the ImmutableString, the function pointers to the get and length methods actually refer to the String.get and String.length method, by going through the base variable which is an internally stored String object.
The use of a function pointer can achieve inheritance of a method from a superclass.
We can further continue to polymorphism in C.
If for example we wanted to change the behavior of the length method to return 0 all the time in the ImmutableString class for some reason, all that would have to be done is to:
Add a function that is going to serve as the overriding length method.
Go to the "constructor" and set the function pointer to the overriding length method.
Adding an overriding length method in ImmutableString may be performed by adding an lengthOverrideMethod:
int lengthOverrideMethod(const void* self)
{
return 0;
}
Then, the function pointer for the length method in the constructor is hooked up to the lengthOverrideMethod:
ImmutableString newImmutableString(const char* value)
{
ImmutableString self = (ImmutableString)malloc(sizeof(struct ImmutableString_Struct));
self->base = newString();
self->get = self->base->get;
self->length = &lengthOverrideMethod;
self->base->set(self->base, (char*)value);
return self;
}
Now, rather than having an identical behavior for the length method in ImmutableString class as the String class, now the length method will refer to the behavior defined in the lengthOverrideMethod function.
I must add a disclaimer that I am still learning how to write with an object-oriented programming style in C, so there probably are points that I didn't explain well, or may just be off mark in terms of how best to implement OOP in C. But my purpose was to try to illustrate one of many uses of function pointers.
For more information on how to perform object-oriented programming in C, please refer to the following questions:
Object-Orientation in C?
Can you write object oriented code in C?
The guide to getting fired: How to abuse function pointers in GCC on x86 machines by compiling your code by hand:
These string literals are bytes of 32-bit x86 machine code. 0xC3 is an x86 ret instruction.
You wouldn't normally write these by hand, you'd write in assembly language and then use an assembler like nasm to assemble it into a flat binary which you hexdump into a C string literal.
Returns the current value on the EAX register
int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))();
Write a swap function
int a = 10, b = 20;
((void(*)(int*,int*))"\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3 <- This swaps the values of a and b")(&a,&b);
Write a for-loop counter to 1000, calling some function each time
((int(*)())"\x66\x31\xc0\x8b\x5c\x24\x04\x66\x40\x50\xff\xd3\x58\x66\x3d\xe8\x03\x75\xf4\xc3")(&function); // calls function with 1->1000
You can even write a recursive function that counts to 100
const char* lol = "\x8b\x5c\x24\x4\x3d\xe8\x3\x0\x0\x7e\x2\x31\xc0\x83\xf8\x64\x7d\x6\x40\x53\xff\xd3\x5b\xc3\xc3 <- Recursively calls the function at address lol.";
i = ((int(*)())(lol))(lol);
Note that compilers place string literals in the .rodata section (or .rdata on Windows), which is linked as part of the text segment (along with code for functions).
The text segment has Read+Exec permission, so casting string literals to function pointers works without needing mprotect() or VirtualProtect() system calls like you'd need for dynamically allocated memory. (Or gcc -z execstack links the program with stack + data segment + heap executable, as a quick hack.)
To disassemble these, you can compile this to put a label on the bytes, and use a disassembler.
// at global scope
const char swap[] = "\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3 <- This swaps the values of a and b";
Compiling with gcc -c -m32 foo.c and disassembling with objdump -D -rwC -Mintel, we can get the assembly, and find out that this code violates the ABI by clobbering EBX (a call-preserved register) and is generally inefficient.
00000000 <swap>:
0: 8b 44 24 04 mov eax,DWORD PTR [esp+0x4] # load int *a arg from the stack
4: 8b 5c 24 08 mov ebx,DWORD PTR [esp+0x8] # ebx = b
8: 8b 00 mov eax,DWORD PTR [eax] # dereference: eax = *a
a: 8b 1b mov ebx,DWORD PTR [ebx]
c: 31 c3 xor ebx,eax # pointless xor-swap
e: 31 d8 xor eax,ebx # instead of just storing with opposite registers
10: 31 c3 xor ebx,eax
12: 8b 4c 24 04 mov ecx,DWORD PTR [esp+0x4] # reload a from the stack
16: 89 01 mov DWORD PTR [ecx],eax # store to *a
18: 8b 4c 24 08 mov ecx,DWORD PTR [esp+0x8]
1c: 89 19 mov DWORD PTR [ecx],ebx
1e: c3 ret
not shown: the later bytes are ASCII text documentation
they're not executed by the CPU because the ret instruction sends execution back to the caller
This machine code will (probably) work in 32-bit code on Windows, Linux, OS X, and so on: the default calling conventions on all those OSes pass args on the stack instead of more efficiently in registers. But EBX is call-preserved in all the normal calling conventions, so using it as a scratch register without saving/restoring it can easily make the caller crash.
One of my favorite uses for function pointers is as cheap and easy iterators -
#include <stdio.h>
#define MAX_COLORS 256
typedef struct {
char* name;
int red;
int green;
int blue;
} Color;
Color Colors[MAX_COLORS];
void eachColor (void (*fp)(Color *c)) {
int i;
for (i=0; i<MAX_COLORS; i++)
(*fp)(&Colors[i]);
}
void printColor(Color* c) {
if (c->name)
printf("%s = %i,%i,%i\n", c->name, c->red, c->green, c->blue);
}
int main() {
Colors[0].name="red";
Colors[0].red=255;
Colors[1].name="blue";
Colors[1].blue=255;
Colors[2].name="black";
eachColor(printColor);
}
Function pointers become easy to declare once you have the basic declarators:
id: ID: ID is a
Pointer: *D: D pointer to
Function: D(<parameters>): D function taking <parameters> returning
While D is another declarator built using those same rules. In the end, somewhere, it ends with ID (see below for an example), which is the name of the declared entity. Let's try to build a function taking a pointer to a function taking nothing and returning int, and returning a pointer to a function taking a char and returning int. With type-defs it's like this
typedef int ReturnFunction(char);
typedef int ParameterFunction(void);
ReturnFunction *f(ParameterFunction *p);
As you see, it's pretty easy to build it up using typedefs. Without typedefs, it's not hard either with the above declarator rules, applied consistently. As you see i missed out the part the pointer points to, and the thing the function returns. That's what appears at the very left of the declaration, and is not of interest: It's added at the end if one built up the declarator already. Let's do that. Building it up consistently, first wordy - showing the structure using [ and ]:
function taking
[pointer to [function taking [void] returning [int]]]
returning
[pointer to [function taking [char] returning [int]]]
As you see, one can describe a type completely by appending declarators one after each other. Construction can be done in two ways. One is bottom-up, starting with the very right thing (leaves) and working the way through up to the identifier. The other way is top-down, starting at the identifier, working the way down to the leaves. I'll show both ways.
Bottom Up
Construction starts with the thing at the right: The thing returned, which is the function taking char. To keep the declarators distinct, i'm going to number them:
D1(char);
Inserted the char parameter directly, since it's trivial. Adding a pointer to declarator by replacing D1 by *D2. Note that we have to wrap parentheses around *D2. That can be known by looking up the precedence of the *-operator and the function-call operator (). Without our parentheses, the compiler would read it as *(D2(char p)). But that would not be a plain replace of D1 by *D2 anymore, of course. Parentheses are always allowed around declarators. So you don't make anything wrong if you add too much of them, actually.
(*D2)(char);
Return type is complete! Now, let's replace D2 by the function declarator function taking <parameters> returning, which is D3(<parameters>) which we are at now.
(*D3(<parameters>))(char)
Note that no parentheses are needed, since we want D3 to be a function-declarator and not a pointer declarator this time. Great, only thing left is the parameters for it. The parameter is done exactly the same as we've done the return type, just with char replaced by void. So i'll copy it:
(*D3( (*ID1)(void)))(char)
I've replaced D2 by ID1, since we are finished with that parameter (it's already a pointer to a function - no need for another declarator). ID1 will be the name of the parameter. Now, i told above at the end one adds the type which all those declarator modify - the one appearing at the very left of every declaration. For functions, that becomes the return type. For pointers the pointed to type etc... It's interesting when written down the type, it will appear in the opposite order, at the very right :) Anyway, substituting it yields the complete declaration. Both times int of course.
int (*ID0(int (*ID1)(void)))(char)
I've called the identifier of the function ID0 in that example.
Top Down
This starts at the identifier at the very left in the description of the type, wrapping that declarator as we walk our way through the right. Start with function taking <parameters> returning
ID0(<parameters>)
The next thing in the description (after "returning") was pointer to. Let's incorporate it:
*ID0(<parameters>)
Then the next thing was functon taking <parameters> returning. The parameter is a simple char, so we put it in right away again, since it's really trivial.
(*ID0(<parameters>))(char)
Note the parentheses we added, since we again want that the * binds first, and then the (char). Otherwise it would read function taking <parameters> returning function .... Noes, functions returning functions aren't even allowed.
Now we just need to put <parameters>. I will show a short version of the deriveration, since i think you already by now have the idea how to do it.
pointer to: *ID1
... function taking void returning: (*ID1)(void)
Just put int before the declarators like we did with bottom-up, and we are finished
int (*ID0(int (*ID1)(void)))(char)
The nice thing
Is bottom-up or top-down better? I'm used to bottom-up, but some people may be more comfortable with top-down. It's a matter of taste i think. Incidentally, if you apply all the operators in that declaration, you will end up getting an int:
int v = (*ID0(some_function_pointer))(some_char);
That is a nice property of declarations in C: The declaration asserts that if those operators are used in an expression using the identifier, then it yields the type on the very left. It's like that for arrays too.
Hope you liked this little tutorial! Now we can link to this when people wonder about the strange declaration syntax of functions. I tried to put as little C internals as possible. Feel free to edit/fix things in it.
Another good use for function pointers:Switching between versions painlessly
They're very handy to use for when you want different functions at different times, or different phases of development. For instance, I'm developing an application on a host computer that has a console, but the final release of the software will be put on an Avnet ZedBoard (which has ports for displays and consoles, but they are not needed/wanted for the final release). So during development, I will use printf to view status and error messages, but when I'm done, I don't want anything printed. Here's what I've done:
version.h
// First, undefine all macros associated with version.h
#undef DEBUG_VERSION
#undef RELEASE_VERSION
#undef INVALID_VERSION
// Define which version we want to use
#define DEBUG_VERSION // The current version
// #define RELEASE_VERSION // To be uncommented when finished debugging
#ifndef __VERSION_H_ /* prevent circular inclusions */
#define __VERSION_H_ /* by using protection macros */
void board_init();
void noprintf(const char *c, ...); // mimic the printf prototype
#endif
// Mimics the printf function prototype. This is what I'll actually
// use to print stuff to the screen
void (* zprintf)(const char*, ...);
// If debug version, use printf
#ifdef DEBUG_VERSION
#include <stdio.h>
#endif
// If both debug and release version, error
#ifdef DEBUG_VERSION
#ifdef RELEASE_VERSION
#define INVALID_VERSION
#endif
#endif
// If neither debug or release version, error
#ifndef DEBUG_VERSION
#ifndef RELEASE_VERSION
#define INVALID_VERSION
#endif
#endif
#ifdef INVALID_VERSION
// Won't allow compilation without a valid version define
#error "Invalid version definition"
#endif
In version.c I will define the 2 function prototypes present in version.h
version.c
#include "version.h"
/*****************************************************************************/
/**
* #name board_init
*
* Sets up the application based on the version type defined in version.h.
* Includes allowing or prohibiting printing to STDOUT.
*
* MUST BE CALLED FIRST THING IN MAIN
*
* #return None
*
*****************************************************************************/
void board_init()
{
// Assign the print function to the correct function pointer
#ifdef DEBUG_VERSION
zprintf = &printf;
#else
// Defined below this function
zprintf = &noprintf;
#endif
}
/*****************************************************************************/
/**
* #name noprintf
*
* simply returns with no actions performed
*
* #return None
*
*****************************************************************************/
void noprintf(const char* c, ...)
{
return;
}
Notice how the function pointer is prototyped in version.h as void (* zprintf)(const char *, ...);When it is referenced in the application, it will start executing wherever it is pointing, which has yet to be defined.
In version.c, notice in the board_init()function where zprintf is assigned a unique function (whose function signature matches) depending on the version that is defined in version.hzprintf = &printf; zprintf calls printf for debugging purposesorzprintf = &noprint; zprintf just returns and will not run unnecessary code
Running the code will look like this:
mainProg.c
#include "version.h"
#include <stdlib.h>
int main()
{
// Must run board_init(), which assigns the function
// pointer to an actual function
board_init();
void *ptr = malloc(100); // Allocate 100 bytes of memory
// malloc returns NULL if unable to allocate the memory.
if (ptr == NULL)
{
zprintf("Unable to allocate memory\n");
return 1;
}
// Other things to do...
return 0;
}
The above code will use printf if in debug mode, or do nothing if in release mode. This is much easier than going through the entire project and commenting out or deleting code. All that I need to do is change the version in version.h and the code will do the rest!
Function pointer is usually defined by typedef, and used as param & return value.
Above answers already explained a lot, I just give a full example:
#include <stdio.h>
#define NUM_A 1
#define NUM_B 2
// define a function pointer type
typedef int (*two_num_operation)(int, int);
// an actual standalone function
static int sum(int a, int b) {
return a + b;
}
// use function pointer as param,
static int sum_via_pointer(int a, int b, two_num_operation funp) {
return (*funp)(a, b);
}
// use function pointer as return value,
static two_num_operation get_sum_fun() {
return ∑
}
// test - use function pointer as variable,
void test_pointer_as_variable() {
// create a pointer to function,
two_num_operation sum_p = ∑
// call function via pointer
printf("pointer as variable:\t %d + %d = %d\n", NUM_A, NUM_B, (*sum_p)(NUM_A, NUM_B));
}
// test - use function pointer as param,
void test_pointer_as_param() {
printf("pointer as param:\t %d + %d = %d\n", NUM_A, NUM_B, sum_via_pointer(NUM_A, NUM_B, &sum));
}
// test - use function pointer as return value,
void test_pointer_as_return_value() {
printf("pointer as return value:\t %d + %d = %d\n", NUM_A, NUM_B, (*get_sum_fun())(NUM_A, NUM_B));
}
int main() {
test_pointer_as_variable();
test_pointer_as_param();
test_pointer_as_return_value();
return 0;
}
A function pointer is a variable that contains the address of a function. Since it is a pointer variable though with some restricted properties, you can use it pretty much like you would any other pointer variable in data structures.
The only exception I can think of is treating the function pointer as pointing to something other than a single value. Doing pointer arithmetic by incrementing or decrementing a function pointer or adding/subtracting an offset to a function pointer isn't really of any utility as a function pointer only points to a single thing, the entry point of a function.
The size of a function pointer variable, the number of bytes occupied by the variable, may vary depending on the underlying architecture, e.g. x32 or x64 or whatever.
The declaration for a function pointer variable needs to specify the same kind of information as a function declaration in order for the C compiler to do the kinds of checks that it normally does. If you don't specify a parameter list in the declaration/definition of the function pointer, the C compiler will not be able to check the use of parameters. There are cases when this lack of checking can be useful however just remember that a safety net has been removed.
Some examples:
int func (int a, char *pStr); // declares a function
int (*pFunc)(int a, char *pStr); // declares or defines a function pointer
int (*pFunc2) (); // declares or defines a function pointer, no parameter list specified.
int (*pFunc3) (void); // declares or defines a function pointer, no arguments.
The first two declararations are somewhat similar in that:
func is a function that takes an int and a char * and returns an int
pFunc is a function pointer to which is assigned the address of a function that takes an int and a char * and returns an int
So from the above we could have a source line in which the address of the function func() is assigned to the function pointer variable pFunc as in pFunc = func;.
Notice the syntax used with a function pointer declaration/definition in which parenthesis are used to overcome the natural operator precedence rules.
int *pfunc(int a, char *pStr); // declares a function that returns int pointer
int (*pFunc)(int a, char *pStr); // declares a function pointer that returns an int
Several Different Usage Examples
Some examples of usage of a function pointer:
int (*pFunc) (int a, char *pStr); // declare a simple function pointer variable
int (*pFunc[55])(int a, char *pStr); // declare an array of 55 function pointers
int (**pFunc)(int a, char *pStr); // declare a pointer to a function pointer variable
struct { // declare a struct that contains a function pointer
int x22;
int (*pFunc)(int a, char *pStr);
} thing = {0, func}; // assign values to the struct variable
char * xF (int x, int (*p)(int a, char *pStr)); // declare a function that has a function pointer as an argument
char * (*pxF) (int x, int (*p)(int a, char *pStr)); // declare a function pointer that points to a function that has a function pointer as an argument
You can use variable length parameter lists in the definition of a function pointer.
int sum (int a, int b, ...);
int (*psum)(int a, int b, ...);
Or you can not specify a parameter list at all. This can be useful but it eliminates the opportunity for the C compiler to perform checks on the argument list provided.
int sum (); // nothing specified in the argument list so could be anything or nothing
int (*psum)();
int sum2(void); // void specified in the argument list so no parameters when calling this function
int (*psum2)(void);
C style Casts
You can use C style casts with function pointers. However be aware that a C compiler may be lax about checks or provide warnings rather than errors.
int sum (int a, char *b);
int (*psplsum) (int a, int b);
psplsum = sum; // generates a compiler warning
psplsum = (int (*)(int a, int b)) sum; // no compiler warning, cast to function pointer
psplsum = (int *(int a, int b)) sum; // compiler error of bad cast generated, parenthesis are required.
Compare Function Pointer to Equality
You can check that a function pointer is equal to a particular function address using an if statement though I am not sure how useful that would be. Other comparison operators would seem to have even less utility.
static int func1(int a, int b) {
return a + b;
}
static int func2(int a, int b, char *c) {
return c[0] + a + b;
}
static int func3(int a, int b, char *x) {
return a + b;
}
static char *func4(int a, int b, char *c, int (*p)())
{
if (p == func1) {
p(a, b);
}
else if (p == func2) {
p(a, b, c); // warning C4047: '==': 'int (__cdecl *)()' differs in levels of indirection from 'char *(__cdecl *)(int,int,char *)'
} else if (p == func3) {
p(a, b, c);
}
return c;
}
An Array of Function Pointers
And if you want to have an array of function pointers each of the elements of which the argument list has differences then you can define a function pointer with the argument list unspecified (not void which means no arguments but just unspecified) something like the following though you may see warnings from the C compiler. This also works for a function pointer parameter to a function:
int(*p[])() = { // an array of function pointers
func1, func2, func3
};
int(**pp)(); // a pointer to a function pointer
p[0](a, b);
p[1](a, b, 0);
p[2](a, b); // oops, left off the last argument but it compiles anyway.
func4(a, b, 0, func1);
func4(a, b, 0, func2); // warning C4047: 'function': 'int (__cdecl *)()' differs in levels of indirection from 'char *(__cdecl *)(int,int,char *)'
func4(a, b, 0, func3);
// iterate over the array elements using an array index
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
func4(a, b, 0, p[i]);
}
// iterate over the array elements using a pointer
for (pp = p; pp < p + sizeof(p)/sizeof(p[0]); pp++) {
(*pp)(a, b, 0); // pointer to a function pointer so must dereference it.
func4(a, b, 0, *pp); // pointer to a function pointer so must dereference it.
}
C style namespace Using Global struct with Function Pointers
You can use the static keyword to specify a function whose name is file scope and then assign this to a global variable as a way of providing something similar to the namespace functionality of C++.
In a header file define a struct that will be our namespace along with a global variable that uses it.
typedef struct {
int (*func1) (int a, int b); // pointer to function that returns an int
char *(*func2) (int a, int b, char *c); // pointer to function that returns a pointer
} FuncThings;
extern const FuncThings FuncThingsGlobal;
Then in the C source file:
#include "header.h"
// the function names used with these static functions do not need to be the
// same as the struct member names. It's just helpful if they are when trying
// to search for them.
// the static keyword ensures these names are file scope only and not visible
// outside of the file.
static int func1 (int a, int b)
{
return a + b;
}
static char *func2 (int a, int b, char *c)
{
c[0] = a % 100; c[1] = b % 50;
return c;
}
const FuncThings FuncThingsGlobal = {func1, func2};
This would then be used by specifying the complete name of global struct variable and member name to access the function. The const modifier is used on the global so that it can not be changed by accident.
int abcd = FuncThingsGlobal.func1 (a, b);
Application Areas of Function Pointers
A DLL library component could do something similar to the C style namespace approach in which a particular library interface is requested from a factory method in a library interface which supports the creation of a struct containing function pointers.. This library interface loads the requested DLL version, creates a struct with the necessary function pointers, and then returns the struct to the requesting caller for use.
typedef struct {
HMODULE hModule;
int (*Func1)();
int (*Func2)();
int(*Func3)(int a, int b);
} LibraryFuncStruct;
int LoadLibraryFunc LPCTSTR dllFileName, LibraryFuncStruct *pStruct)
{
int retStatus = 0; // default is an error detected
pStruct->hModule = LoadLibrary (dllFileName);
if (pStruct->hModule) {
pStruct->Func1 = (int (*)()) GetProcAddress (pStruct->hModule, "Func1");
pStruct->Func2 = (int (*)()) GetProcAddress (pStruct->hModule, "Func2");
pStruct->Func3 = (int (*)(int a, int b)) GetProcAddress(pStruct->hModule, "Func3");
retStatus = 1;
}
return retStatus;
}
void FreeLibraryFunc (LibraryFuncStruct *pStruct)
{
if (pStruct->hModule) FreeLibrary (pStruct->hModule);
pStruct->hModule = 0;
}
and this could be used as in:
LibraryFuncStruct myLib = {0};
LoadLibraryFunc (L"library.dll", &myLib);
// ....
myLib.Func1();
// ....
FreeLibraryFunc (&myLib);
The same approach can be used to define an abstract hardware layer for code that uses a particular model of the underlying hardware. Function pointers are filled in with hardware specific functions by a factory to provide the hardware specific functionality that implements functions specified in the abstract hardware model. This can be used to provide an abstract hardware layer used by software which calls a factory function in order to get the specific hardware function interface then uses the function pointers provided to perform actions for the underlying hardware without needing to know implementation details about the specific target.
Function Pointers to create Delegates, Handlers, and Callbacks
You can use function pointers as a way to delegate some task or functionality. The classic example in C is the comparison delegate function pointer used with the Standard C library functions qsort() and bsearch() to provide the collation order for sorting a list of items or performing a binary search over a sorted list of items. The comparison function delegate specifies the collation algorithm used in the sort or the binary search.
Another use is similar to applying an algorithm to a C++ Standard Template Library container.
void * ApplyAlgorithm (void *pArray, size_t sizeItem, size_t nItems, int (*p)(void *)) {
unsigned char *pList = pArray;
unsigned char *pListEnd = pList + nItems * sizeItem;
for ( ; pList < pListEnd; pList += sizeItem) {
p (pList);
}
return pArray;
}
int pIncrement(int *pI) {
(*pI)++;
return 1;
}
void * ApplyFold(void *pArray, size_t sizeItem, size_t nItems, void * pResult, int(*p)(void *, void *)) {
unsigned char *pList = pArray;
unsigned char *pListEnd = pList + nItems * sizeItem;
for (; pList < pListEnd; pList += sizeItem) {
p(pList, pResult);
}
return pArray;
}
int pSummation(int *pI, int *pSum) {
(*pSum) += *pI;
return 1;
}
// source code and then lets use our function.
int intList[30] = { 0 }, iSum = 0;
ApplyAlgorithm(intList, sizeof(int), sizeof(intList) / sizeof(intList[0]), pIncrement);
ApplyFold(intList, sizeof(int), sizeof(intList) / sizeof(intList[0]), &iSum, pSummation);
Another example is with GUI source code in which a handler for a particular event is registered by providing a function pointer which is actually called when the event happens. The Microsoft MFC framework with its message maps uses something similar to handle Windows messages that are delivered to a window or thread.
Asynchronous functions that require a callback are similar to an event handler. The user of the asynchronous function calls the asynchronous function to start some action and provides a function pointer which the asynchronous function will call once the action is complete. In this case the event is the asynchronous function completing its task.
Starting from scratch function has Some Memory Address From Where They start executing. In Assembly Language They Are called as (call "function's memory address").Now come back to C If function has a memory address then they can be manipulated by Pointers in C.So By the rules of C
1.First you need to declare a pointer to function
2.Pass the Address of the Desired function
****Note->the functions should be of same type****
This Simple Programme will Illustrate Every Thing.
#include<stdio.h>
void (*print)() ;//Declare a Function Pointers
void sayhello();//Declare The Function Whose Address is to be passed
//The Functions should Be of Same Type
int main()
{
print=sayhello;//Addressof sayhello is assigned to print
print();//print Does A call To The Function
return 0;
}
void sayhello()
{
printf("\n Hello World");
}
After That lets See How machine Understands Them.Glimpse of machine instruction of the above programme in 32 bit architecture.
The red mark area is showing how the address is being exchanged and storing in eax. Then their is a call instruction on eax. eax contains the desired address of the function.
One of the big uses for function pointers in C is to call a function selected at run-time. For example, the C run-time library has two routines, qsort and bsearch, which take a pointer to a function that is called to compare two items being sorted; this allows you to sort or search, respectively, anything, based on any criteria you wish to use.
A very basic example, if there is one function called print(int x, int y) which in turn may require to call a function (either add() or sub(), which are of the same type) then what we will do, we will add one function pointer argument to the print() function as shown below:
#include <stdio.h>
int add()
{
return (100+10);
}
int sub()
{
return (100-10);
}
void print(int x, int y, int (*func)())
{
printf("value is: %d\n", (x+y+(*func)()));
}
int main()
{
int x=100, y=200;
print(x,y,add);
print(x,y,sub);
return 0;
}
The output is:
value is: 410
value is: 390
Since function pointers are often typed callbacks, you might want to have a look at type safe callbacks. The same applies to entry points, etc of functions that are not callbacks.
C is quite fickle and forgiving at the same time :)
Pointers to functions are useful because, as "The C Programming Language" book says, functions in C are not variables.
This means,
// Say you have add function
int add(int x, int y){
return x + y;
}
// Say you have another add function
int another_add(int x, int y){
return y + x;
}
int main(){
// Although the types of another_add and add are same
// You can't do
another_add = add
// You have a compute function that takes a function of int's signature
int (*compute)(int, int);
// You won't even be able to pass functions to other functions
// (Although when you do, C is just passing the pointer to that function)
// So, compute(add) is really compute(&add)
// But you can create a pointer to functions that are variables
// you can assign to and/or pass to other functions
int (*operation)(int, int);
// Now you can do
operation = &add;
// You could also do, the following to do the same thing
// When a function is passed in right hand side of assignment,
// C knows that you mean pointer, and you don't need explicit &
operation = add;
}
Similarly, an array is also not a variable in C. You can make up a similar example as above and test out.
I had some experience lately with function pointers in C.
So going on with the tradition of answering your own questions, I decided to make a small summary of the very basics, for those who need a quick dive-in to the subject.
Function pointers in C
Let's start with a basic function which we will be pointing to:
int addInt(int n, int m) {
return n+m;
}
First thing, let's define a pointer to a function which receives 2 ints and returns an int:
int (*functionPtr)(int,int);
Now we can safely point to our function:
functionPtr = &addInt;
Now that we have a pointer to the function, let's use it:
int sum = (*functionPtr)(2, 3); // sum == 5
Passing the pointer to another function is basically the same:
int add2to3(int (*functionPtr)(int, int)) {
return (*functionPtr)(2, 3);
}
We can use function pointers in return values as well (try to keep up, it gets messy):
// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
printf("Got parameter %d", n);
int (*functionPtr)(int,int) = &addInt;
return functionPtr;
}
But it's much nicer to use a typedef:
typedef int (*myFuncDef)(int, int);
// note that the typedef name is indeed myFuncDef
myFuncDef functionFactory(int n) {
printf("Got parameter %d", n);
myFuncDef functionPtr = &addInt;
return functionPtr;
}
Function pointers in C can be used to perform object-oriented programming in C.
For example, the following lines is written in C:
String s1 = newString();
s1->set(s1, "hello");
Yes, the -> and the lack of a new operator is a dead give away, but it sure seems to imply that we're setting the text of some String class to be "hello".
By using function pointers, it is possible to emulate methods in C.
How is this accomplished?
The String class is actually a struct with a bunch of function pointers which act as a way to simulate methods. The following is a partial declaration of the String class:
typedef struct String_Struct* String;
struct String_Struct
{
char* (*get)(const void* self);
void (*set)(const void* self, char* value);
int (*length)(const void* self);
};
char* getString(const void* self);
void setString(const void* self, char* value);
int lengthString(const void* self);
String newString();
As can be seen, the methods of the String class are actually function pointers to the declared function. In preparing the instance of the String, the newString function is called in order to set up the function pointers to their respective functions:
String newString()
{
String self = (String)malloc(sizeof(struct String_Struct));
self->get = &getString;
self->set = &setString;
self->length = &lengthString;
self->set(self, "");
return self;
}
For example, the getString function that is called by invoking the get method is defined as the following:
char* getString(const void* self_obj)
{
return ((String)self_obj)->internal->value;
}
One thing that can be noticed is that there is no concept of an instance of an object and having methods that are actually a part of an object, so a "self object" must be passed in on each invocation. (And the internal is just a hidden struct which was omitted from the code listing earlier -- it is a way of performing information hiding, but that is not relevant to function pointers.)
So, rather than being able to do s1->set("hello");, one must pass in the object to perform the action on s1->set(s1, "hello").
With that minor explanation having to pass in a reference to yourself out of the way, we'll move to the next part, which is inheritance in C.
Let's say we want to make a subclass of String, say an ImmutableString. In order to make the string immutable, the set method will not be accessible, while maintaining access to get and length, and force the "constructor" to accept a char*:
typedef struct ImmutableString_Struct* ImmutableString;
struct ImmutableString_Struct
{
String base;
char* (*get)(const void* self);
int (*length)(const void* self);
};
ImmutableString newImmutableString(const char* value);
Basically, for all subclasses, the available methods are once again function pointers. This time, the declaration for the set method is not present, therefore, it cannot be called in a ImmutableString.
As for the implementation of the ImmutableString, the only relevant code is the "constructor" function, the newImmutableString:
ImmutableString newImmutableString(const char* value)
{
ImmutableString self = (ImmutableString)malloc(sizeof(struct ImmutableString_Struct));
self->base = newString();
self->get = self->base->get;
self->length = self->base->length;
self->base->set(self->base, (char*)value);
return self;
}
In instantiating the ImmutableString, the function pointers to the get and length methods actually refer to the String.get and String.length method, by going through the base variable which is an internally stored String object.
The use of a function pointer can achieve inheritance of a method from a superclass.
We can further continue to polymorphism in C.
If for example we wanted to change the behavior of the length method to return 0 all the time in the ImmutableString class for some reason, all that would have to be done is to:
Add a function that is going to serve as the overriding length method.
Go to the "constructor" and set the function pointer to the overriding length method.
Adding an overriding length method in ImmutableString may be performed by adding an lengthOverrideMethod:
int lengthOverrideMethod(const void* self)
{
return 0;
}
Then, the function pointer for the length method in the constructor is hooked up to the lengthOverrideMethod:
ImmutableString newImmutableString(const char* value)
{
ImmutableString self = (ImmutableString)malloc(sizeof(struct ImmutableString_Struct));
self->base = newString();
self->get = self->base->get;
self->length = &lengthOverrideMethod;
self->base->set(self->base, (char*)value);
return self;
}
Now, rather than having an identical behavior for the length method in ImmutableString class as the String class, now the length method will refer to the behavior defined in the lengthOverrideMethod function.
I must add a disclaimer that I am still learning how to write with an object-oriented programming style in C, so there probably are points that I didn't explain well, or may just be off mark in terms of how best to implement OOP in C. But my purpose was to try to illustrate one of many uses of function pointers.
For more information on how to perform object-oriented programming in C, please refer to the following questions:
Object-Orientation in C?
Can you write object oriented code in C?
The guide to getting fired: How to abuse function pointers in GCC on x86 machines by compiling your code by hand:
These string literals are bytes of 32-bit x86 machine code. 0xC3 is an x86 ret instruction.
You wouldn't normally write these by hand, you'd write in assembly language and then use an assembler like nasm to assemble it into a flat binary which you hexdump into a C string literal.
Returns the current value on the EAX register
int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))();
Write a swap function
int a = 10, b = 20;
((void(*)(int*,int*))"\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3 <- This swaps the values of a and b")(&a,&b);
Write a for-loop counter to 1000, calling some function each time
((int(*)())"\x66\x31\xc0\x8b\x5c\x24\x04\x66\x40\x50\xff\xd3\x58\x66\x3d\xe8\x03\x75\xf4\xc3")(&function); // calls function with 1->1000
You can even write a recursive function that counts to 100
const char* lol = "\x8b\x5c\x24\x4\x3d\xe8\x3\x0\x0\x7e\x2\x31\xc0\x83\xf8\x64\x7d\x6\x40\x53\xff\xd3\x5b\xc3\xc3 <- Recursively calls the function at address lol.";
i = ((int(*)())(lol))(lol);
Note that compilers place string literals in the .rodata section (or .rdata on Windows), which is linked as part of the text segment (along with code for functions).
The text segment has Read+Exec permission, so casting string literals to function pointers works without needing mprotect() or VirtualProtect() system calls like you'd need for dynamically allocated memory. (Or gcc -z execstack links the program with stack + data segment + heap executable, as a quick hack.)
To disassemble these, you can compile this to put a label on the bytes, and use a disassembler.
// at global scope
const char swap[] = "\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3 <- This swaps the values of a and b";
Compiling with gcc -c -m32 foo.c and disassembling with objdump -D -rwC -Mintel, we can get the assembly, and find out that this code violates the ABI by clobbering EBX (a call-preserved register) and is generally inefficient.
00000000 <swap>:
0: 8b 44 24 04 mov eax,DWORD PTR [esp+0x4] # load int *a arg from the stack
4: 8b 5c 24 08 mov ebx,DWORD PTR [esp+0x8] # ebx = b
8: 8b 00 mov eax,DWORD PTR [eax] # dereference: eax = *a
a: 8b 1b mov ebx,DWORD PTR [ebx]
c: 31 c3 xor ebx,eax # pointless xor-swap
e: 31 d8 xor eax,ebx # instead of just storing with opposite registers
10: 31 c3 xor ebx,eax
12: 8b 4c 24 04 mov ecx,DWORD PTR [esp+0x4] # reload a from the stack
16: 89 01 mov DWORD PTR [ecx],eax # store to *a
18: 8b 4c 24 08 mov ecx,DWORD PTR [esp+0x8]
1c: 89 19 mov DWORD PTR [ecx],ebx
1e: c3 ret
not shown: the later bytes are ASCII text documentation
they're not executed by the CPU because the ret instruction sends execution back to the caller
This machine code will (probably) work in 32-bit code on Windows, Linux, OS X, and so on: the default calling conventions on all those OSes pass args on the stack instead of more efficiently in registers. But EBX is call-preserved in all the normal calling conventions, so using it as a scratch register without saving/restoring it can easily make the caller crash.
One of my favorite uses for function pointers is as cheap and easy iterators -
#include <stdio.h>
#define MAX_COLORS 256
typedef struct {
char* name;
int red;
int green;
int blue;
} Color;
Color Colors[MAX_COLORS];
void eachColor (void (*fp)(Color *c)) {
int i;
for (i=0; i<MAX_COLORS; i++)
(*fp)(&Colors[i]);
}
void printColor(Color* c) {
if (c->name)
printf("%s = %i,%i,%i\n", c->name, c->red, c->green, c->blue);
}
int main() {
Colors[0].name="red";
Colors[0].red=255;
Colors[1].name="blue";
Colors[1].blue=255;
Colors[2].name="black";
eachColor(printColor);
}
Function pointers become easy to declare once you have the basic declarators:
id: ID: ID is a
Pointer: *D: D pointer to
Function: D(<parameters>): D function taking <parameters> returning
While D is another declarator built using those same rules. In the end, somewhere, it ends with ID (see below for an example), which is the name of the declared entity. Let's try to build a function taking a pointer to a function taking nothing and returning int, and returning a pointer to a function taking a char and returning int. With type-defs it's like this
typedef int ReturnFunction(char);
typedef int ParameterFunction(void);
ReturnFunction *f(ParameterFunction *p);
As you see, it's pretty easy to build it up using typedefs. Without typedefs, it's not hard either with the above declarator rules, applied consistently. As you see i missed out the part the pointer points to, and the thing the function returns. That's what appears at the very left of the declaration, and is not of interest: It's added at the end if one built up the declarator already. Let's do that. Building it up consistently, first wordy - showing the structure using [ and ]:
function taking
[pointer to [function taking [void] returning [int]]]
returning
[pointer to [function taking [char] returning [int]]]
As you see, one can describe a type completely by appending declarators one after each other. Construction can be done in two ways. One is bottom-up, starting with the very right thing (leaves) and working the way through up to the identifier. The other way is top-down, starting at the identifier, working the way down to the leaves. I'll show both ways.
Bottom Up
Construction starts with the thing at the right: The thing returned, which is the function taking char. To keep the declarators distinct, i'm going to number them:
D1(char);
Inserted the char parameter directly, since it's trivial. Adding a pointer to declarator by replacing D1 by *D2. Note that we have to wrap parentheses around *D2. That can be known by looking up the precedence of the *-operator and the function-call operator (). Without our parentheses, the compiler would read it as *(D2(char p)). But that would not be a plain replace of D1 by *D2 anymore, of course. Parentheses are always allowed around declarators. So you don't make anything wrong if you add too much of them, actually.
(*D2)(char);
Return type is complete! Now, let's replace D2 by the function declarator function taking <parameters> returning, which is D3(<parameters>) which we are at now.
(*D3(<parameters>))(char)
Note that no parentheses are needed, since we want D3 to be a function-declarator and not a pointer declarator this time. Great, only thing left is the parameters for it. The parameter is done exactly the same as we've done the return type, just with char replaced by void. So i'll copy it:
(*D3( (*ID1)(void)))(char)
I've replaced D2 by ID1, since we are finished with that parameter (it's already a pointer to a function - no need for another declarator). ID1 will be the name of the parameter. Now, i told above at the end one adds the type which all those declarator modify - the one appearing at the very left of every declaration. For functions, that becomes the return type. For pointers the pointed to type etc... It's interesting when written down the type, it will appear in the opposite order, at the very right :) Anyway, substituting it yields the complete declaration. Both times int of course.
int (*ID0(int (*ID1)(void)))(char)
I've called the identifier of the function ID0 in that example.
Top Down
This starts at the identifier at the very left in the description of the type, wrapping that declarator as we walk our way through the right. Start with function taking <parameters> returning
ID0(<parameters>)
The next thing in the description (after "returning") was pointer to. Let's incorporate it:
*ID0(<parameters>)
Then the next thing was functon taking <parameters> returning. The parameter is a simple char, so we put it in right away again, since it's really trivial.
(*ID0(<parameters>))(char)
Note the parentheses we added, since we again want that the * binds first, and then the (char). Otherwise it would read function taking <parameters> returning function .... Noes, functions returning functions aren't even allowed.
Now we just need to put <parameters>. I will show a short version of the deriveration, since i think you already by now have the idea how to do it.
pointer to: *ID1
... function taking void returning: (*ID1)(void)
Just put int before the declarators like we did with bottom-up, and we are finished
int (*ID0(int (*ID1)(void)))(char)
The nice thing
Is bottom-up or top-down better? I'm used to bottom-up, but some people may be more comfortable with top-down. It's a matter of taste i think. Incidentally, if you apply all the operators in that declaration, you will end up getting an int:
int v = (*ID0(some_function_pointer))(some_char);
That is a nice property of declarations in C: The declaration asserts that if those operators are used in an expression using the identifier, then it yields the type on the very left. It's like that for arrays too.
Hope you liked this little tutorial! Now we can link to this when people wonder about the strange declaration syntax of functions. I tried to put as little C internals as possible. Feel free to edit/fix things in it.
Another good use for function pointers:Switching between versions painlessly
They're very handy to use for when you want different functions at different times, or different phases of development. For instance, I'm developing an application on a host computer that has a console, but the final release of the software will be put on an Avnet ZedBoard (which has ports for displays and consoles, but they are not needed/wanted for the final release). So during development, I will use printf to view status and error messages, but when I'm done, I don't want anything printed. Here's what I've done:
version.h
// First, undefine all macros associated with version.h
#undef DEBUG_VERSION
#undef RELEASE_VERSION
#undef INVALID_VERSION
// Define which version we want to use
#define DEBUG_VERSION // The current version
// #define RELEASE_VERSION // To be uncommented when finished debugging
#ifndef __VERSION_H_ /* prevent circular inclusions */
#define __VERSION_H_ /* by using protection macros */
void board_init();
void noprintf(const char *c, ...); // mimic the printf prototype
#endif
// Mimics the printf function prototype. This is what I'll actually
// use to print stuff to the screen
void (* zprintf)(const char*, ...);
// If debug version, use printf
#ifdef DEBUG_VERSION
#include <stdio.h>
#endif
// If both debug and release version, error
#ifdef DEBUG_VERSION
#ifdef RELEASE_VERSION
#define INVALID_VERSION
#endif
#endif
// If neither debug or release version, error
#ifndef DEBUG_VERSION
#ifndef RELEASE_VERSION
#define INVALID_VERSION
#endif
#endif
#ifdef INVALID_VERSION
// Won't allow compilation without a valid version define
#error "Invalid version definition"
#endif
In version.c I will define the 2 function prototypes present in version.h
version.c
#include "version.h"
/*****************************************************************************/
/**
* #name board_init
*
* Sets up the application based on the version type defined in version.h.
* Includes allowing or prohibiting printing to STDOUT.
*
* MUST BE CALLED FIRST THING IN MAIN
*
* #return None
*
*****************************************************************************/
void board_init()
{
// Assign the print function to the correct function pointer
#ifdef DEBUG_VERSION
zprintf = &printf;
#else
// Defined below this function
zprintf = &noprintf;
#endif
}
/*****************************************************************************/
/**
* #name noprintf
*
* simply returns with no actions performed
*
* #return None
*
*****************************************************************************/
void noprintf(const char* c, ...)
{
return;
}
Notice how the function pointer is prototyped in version.h as void (* zprintf)(const char *, ...);When it is referenced in the application, it will start executing wherever it is pointing, which has yet to be defined.
In version.c, notice in the board_init()function where zprintf is assigned a unique function (whose function signature matches) depending on the version that is defined in version.hzprintf = &printf; zprintf calls printf for debugging purposesorzprintf = &noprint; zprintf just returns and will not run unnecessary code
Running the code will look like this:
mainProg.c
#include "version.h"
#include <stdlib.h>
int main()
{
// Must run board_init(), which assigns the function
// pointer to an actual function
board_init();
void *ptr = malloc(100); // Allocate 100 bytes of memory
// malloc returns NULL if unable to allocate the memory.
if (ptr == NULL)
{
zprintf("Unable to allocate memory\n");
return 1;
}
// Other things to do...
return 0;
}
The above code will use printf if in debug mode, or do nothing if in release mode. This is much easier than going through the entire project and commenting out or deleting code. All that I need to do is change the version in version.h and the code will do the rest!
Function pointer is usually defined by typedef, and used as param & return value.
Above answers already explained a lot, I just give a full example:
#include <stdio.h>
#define NUM_A 1
#define NUM_B 2
// define a function pointer type
typedef int (*two_num_operation)(int, int);
// an actual standalone function
static int sum(int a, int b) {
return a + b;
}
// use function pointer as param,
static int sum_via_pointer(int a, int b, two_num_operation funp) {
return (*funp)(a, b);
}
// use function pointer as return value,
static two_num_operation get_sum_fun() {
return ∑
}
// test - use function pointer as variable,
void test_pointer_as_variable() {
// create a pointer to function,
two_num_operation sum_p = ∑
// call function via pointer
printf("pointer as variable:\t %d + %d = %d\n", NUM_A, NUM_B, (*sum_p)(NUM_A, NUM_B));
}
// test - use function pointer as param,
void test_pointer_as_param() {
printf("pointer as param:\t %d + %d = %d\n", NUM_A, NUM_B, sum_via_pointer(NUM_A, NUM_B, &sum));
}
// test - use function pointer as return value,
void test_pointer_as_return_value() {
printf("pointer as return value:\t %d + %d = %d\n", NUM_A, NUM_B, (*get_sum_fun())(NUM_A, NUM_B));
}
int main() {
test_pointer_as_variable();
test_pointer_as_param();
test_pointer_as_return_value();
return 0;
}
A function pointer is a variable that contains the address of a function. Since it is a pointer variable though with some restricted properties, you can use it pretty much like you would any other pointer variable in data structures.
The only exception I can think of is treating the function pointer as pointing to something other than a single value. Doing pointer arithmetic by incrementing or decrementing a function pointer or adding/subtracting an offset to a function pointer isn't really of any utility as a function pointer only points to a single thing, the entry point of a function.
The size of a function pointer variable, the number of bytes occupied by the variable, may vary depending on the underlying architecture, e.g. x32 or x64 or whatever.
The declaration for a function pointer variable needs to specify the same kind of information as a function declaration in order for the C compiler to do the kinds of checks that it normally does. If you don't specify a parameter list in the declaration/definition of the function pointer, the C compiler will not be able to check the use of parameters. There are cases when this lack of checking can be useful however just remember that a safety net has been removed.
Some examples:
int func (int a, char *pStr); // declares a function
int (*pFunc)(int a, char *pStr); // declares or defines a function pointer
int (*pFunc2) (); // declares or defines a function pointer, no parameter list specified.
int (*pFunc3) (void); // declares or defines a function pointer, no arguments.
The first two declararations are somewhat similar in that:
func is a function that takes an int and a char * and returns an int
pFunc is a function pointer to which is assigned the address of a function that takes an int and a char * and returns an int
So from the above we could have a source line in which the address of the function func() is assigned to the function pointer variable pFunc as in pFunc = func;.
Notice the syntax used with a function pointer declaration/definition in which parenthesis are used to overcome the natural operator precedence rules.
int *pfunc(int a, char *pStr); // declares a function that returns int pointer
int (*pFunc)(int a, char *pStr); // declares a function pointer that returns an int
Several Different Usage Examples
Some examples of usage of a function pointer:
int (*pFunc) (int a, char *pStr); // declare a simple function pointer variable
int (*pFunc[55])(int a, char *pStr); // declare an array of 55 function pointers
int (**pFunc)(int a, char *pStr); // declare a pointer to a function pointer variable
struct { // declare a struct that contains a function pointer
int x22;
int (*pFunc)(int a, char *pStr);
} thing = {0, func}; // assign values to the struct variable
char * xF (int x, int (*p)(int a, char *pStr)); // declare a function that has a function pointer as an argument
char * (*pxF) (int x, int (*p)(int a, char *pStr)); // declare a function pointer that points to a function that has a function pointer as an argument
You can use variable length parameter lists in the definition of a function pointer.
int sum (int a, int b, ...);
int (*psum)(int a, int b, ...);
Or you can not specify a parameter list at all. This can be useful but it eliminates the opportunity for the C compiler to perform checks on the argument list provided.
int sum (); // nothing specified in the argument list so could be anything or nothing
int (*psum)();
int sum2(void); // void specified in the argument list so no parameters when calling this function
int (*psum2)(void);
C style Casts
You can use C style casts with function pointers. However be aware that a C compiler may be lax about checks or provide warnings rather than errors.
int sum (int a, char *b);
int (*psplsum) (int a, int b);
psplsum = sum; // generates a compiler warning
psplsum = (int (*)(int a, int b)) sum; // no compiler warning, cast to function pointer
psplsum = (int *(int a, int b)) sum; // compiler error of bad cast generated, parenthesis are required.
Compare Function Pointer to Equality
You can check that a function pointer is equal to a particular function address using an if statement though I am not sure how useful that would be. Other comparison operators would seem to have even less utility.
static int func1(int a, int b) {
return a + b;
}
static int func2(int a, int b, char *c) {
return c[0] + a + b;
}
static int func3(int a, int b, char *x) {
return a + b;
}
static char *func4(int a, int b, char *c, int (*p)())
{
if (p == func1) {
p(a, b);
}
else if (p == func2) {
p(a, b, c); // warning C4047: '==': 'int (__cdecl *)()' differs in levels of indirection from 'char *(__cdecl *)(int,int,char *)'
} else if (p == func3) {
p(a, b, c);
}
return c;
}
An Array of Function Pointers
And if you want to have an array of function pointers each of the elements of which the argument list has differences then you can define a function pointer with the argument list unspecified (not void which means no arguments but just unspecified) something like the following though you may see warnings from the C compiler. This also works for a function pointer parameter to a function:
int(*p[])() = { // an array of function pointers
func1, func2, func3
};
int(**pp)(); // a pointer to a function pointer
p[0](a, b);
p[1](a, b, 0);
p[2](a, b); // oops, left off the last argument but it compiles anyway.
func4(a, b, 0, func1);
func4(a, b, 0, func2); // warning C4047: 'function': 'int (__cdecl *)()' differs in levels of indirection from 'char *(__cdecl *)(int,int,char *)'
func4(a, b, 0, func3);
// iterate over the array elements using an array index
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
func4(a, b, 0, p[i]);
}
// iterate over the array elements using a pointer
for (pp = p; pp < p + sizeof(p)/sizeof(p[0]); pp++) {
(*pp)(a, b, 0); // pointer to a function pointer so must dereference it.
func4(a, b, 0, *pp); // pointer to a function pointer so must dereference it.
}
C style namespace Using Global struct with Function Pointers
You can use the static keyword to specify a function whose name is file scope and then assign this to a global variable as a way of providing something similar to the namespace functionality of C++.
In a header file define a struct that will be our namespace along with a global variable that uses it.
typedef struct {
int (*func1) (int a, int b); // pointer to function that returns an int
char *(*func2) (int a, int b, char *c); // pointer to function that returns a pointer
} FuncThings;
extern const FuncThings FuncThingsGlobal;
Then in the C source file:
#include "header.h"
// the function names used with these static functions do not need to be the
// same as the struct member names. It's just helpful if they are when trying
// to search for them.
// the static keyword ensures these names are file scope only and not visible
// outside of the file.
static int func1 (int a, int b)
{
return a + b;
}
static char *func2 (int a, int b, char *c)
{
c[0] = a % 100; c[1] = b % 50;
return c;
}
const FuncThings FuncThingsGlobal = {func1, func2};
This would then be used by specifying the complete name of global struct variable and member name to access the function. The const modifier is used on the global so that it can not be changed by accident.
int abcd = FuncThingsGlobal.func1 (a, b);
Application Areas of Function Pointers
A DLL library component could do something similar to the C style namespace approach in which a particular library interface is requested from a factory method in a library interface which supports the creation of a struct containing function pointers.. This library interface loads the requested DLL version, creates a struct with the necessary function pointers, and then returns the struct to the requesting caller for use.
typedef struct {
HMODULE hModule;
int (*Func1)();
int (*Func2)();
int(*Func3)(int a, int b);
} LibraryFuncStruct;
int LoadLibraryFunc LPCTSTR dllFileName, LibraryFuncStruct *pStruct)
{
int retStatus = 0; // default is an error detected
pStruct->hModule = LoadLibrary (dllFileName);
if (pStruct->hModule) {
pStruct->Func1 = (int (*)()) GetProcAddress (pStruct->hModule, "Func1");
pStruct->Func2 = (int (*)()) GetProcAddress (pStruct->hModule, "Func2");
pStruct->Func3 = (int (*)(int a, int b)) GetProcAddress(pStruct->hModule, "Func3");
retStatus = 1;
}
return retStatus;
}
void FreeLibraryFunc (LibraryFuncStruct *pStruct)
{
if (pStruct->hModule) FreeLibrary (pStruct->hModule);
pStruct->hModule = 0;
}
and this could be used as in:
LibraryFuncStruct myLib = {0};
LoadLibraryFunc (L"library.dll", &myLib);
// ....
myLib.Func1();
// ....
FreeLibraryFunc (&myLib);
The same approach can be used to define an abstract hardware layer for code that uses a particular model of the underlying hardware. Function pointers are filled in with hardware specific functions by a factory to provide the hardware specific functionality that implements functions specified in the abstract hardware model. This can be used to provide an abstract hardware layer used by software which calls a factory function in order to get the specific hardware function interface then uses the function pointers provided to perform actions for the underlying hardware without needing to know implementation details about the specific target.
Function Pointers to create Delegates, Handlers, and Callbacks
You can use function pointers as a way to delegate some task or functionality. The classic example in C is the comparison delegate function pointer used with the Standard C library functions qsort() and bsearch() to provide the collation order for sorting a list of items or performing a binary search over a sorted list of items. The comparison function delegate specifies the collation algorithm used in the sort or the binary search.
Another use is similar to applying an algorithm to a C++ Standard Template Library container.
void * ApplyAlgorithm (void *pArray, size_t sizeItem, size_t nItems, int (*p)(void *)) {
unsigned char *pList = pArray;
unsigned char *pListEnd = pList + nItems * sizeItem;
for ( ; pList < pListEnd; pList += sizeItem) {
p (pList);
}
return pArray;
}
int pIncrement(int *pI) {
(*pI)++;
return 1;
}
void * ApplyFold(void *pArray, size_t sizeItem, size_t nItems, void * pResult, int(*p)(void *, void *)) {
unsigned char *pList = pArray;
unsigned char *pListEnd = pList + nItems * sizeItem;
for (; pList < pListEnd; pList += sizeItem) {
p(pList, pResult);
}
return pArray;
}
int pSummation(int *pI, int *pSum) {
(*pSum) += *pI;
return 1;
}
// source code and then lets use our function.
int intList[30] = { 0 }, iSum = 0;
ApplyAlgorithm(intList, sizeof(int), sizeof(intList) / sizeof(intList[0]), pIncrement);
ApplyFold(intList, sizeof(int), sizeof(intList) / sizeof(intList[0]), &iSum, pSummation);
Another example is with GUI source code in which a handler for a particular event is registered by providing a function pointer which is actually called when the event happens. The Microsoft MFC framework with its message maps uses something similar to handle Windows messages that are delivered to a window or thread.
Asynchronous functions that require a callback are similar to an event handler. The user of the asynchronous function calls the asynchronous function to start some action and provides a function pointer which the asynchronous function will call once the action is complete. In this case the event is the asynchronous function completing its task.
Starting from scratch function has Some Memory Address From Where They start executing. In Assembly Language They Are called as (call "function's memory address").Now come back to C If function has a memory address then they can be manipulated by Pointers in C.So By the rules of C
1.First you need to declare a pointer to function
2.Pass the Address of the Desired function
****Note->the functions should be of same type****
This Simple Programme will Illustrate Every Thing.
#include<stdio.h>
void (*print)() ;//Declare a Function Pointers
void sayhello();//Declare The Function Whose Address is to be passed
//The Functions should Be of Same Type
int main()
{
print=sayhello;//Addressof sayhello is assigned to print
print();//print Does A call To The Function
return 0;
}
void sayhello()
{
printf("\n Hello World");
}
After That lets See How machine Understands Them.Glimpse of machine instruction of the above programme in 32 bit architecture.
The red mark area is showing how the address is being exchanged and storing in eax. Then their is a call instruction on eax. eax contains the desired address of the function.
One of the big uses for function pointers in C is to call a function selected at run-time. For example, the C run-time library has two routines, qsort and bsearch, which take a pointer to a function that is called to compare two items being sorted; this allows you to sort or search, respectively, anything, based on any criteria you wish to use.
A very basic example, if there is one function called print(int x, int y) which in turn may require to call a function (either add() or sub(), which are of the same type) then what we will do, we will add one function pointer argument to the print() function as shown below:
#include <stdio.h>
int add()
{
return (100+10);
}
int sub()
{
return (100-10);
}
void print(int x, int y, int (*func)())
{
printf("value is: %d\n", (x+y+(*func)()));
}
int main()
{
int x=100, y=200;
print(x,y,add);
print(x,y,sub);
return 0;
}
The output is:
value is: 410
value is: 390
Since function pointers are often typed callbacks, you might want to have a look at type safe callbacks. The same applies to entry points, etc of functions that are not callbacks.
C is quite fickle and forgiving at the same time :)
Pointers to functions are useful because, as "The C Programming Language" book says, functions in C are not variables.
This means,
// Say you have add function
int add(int x, int y){
return x + y;
}
// Say you have another add function
int another_add(int x, int y){
return y + x;
}
int main(){
// Although the types of another_add and add are same
// You can't do
another_add = add
// You have a compute function that takes a function of int's signature
int (*compute)(int, int);
// You won't even be able to pass functions to other functions
// (Although when you do, C is just passing the pointer to that function)
// So, compute(add) is really compute(&add)
// But you can create a pointer to functions that are variables
// you can assign to and/or pass to other functions
int (*operation)(int, int);
// Now you can do
operation = &add;
// You could also do, the following to do the same thing
// When a function is passed in right hand side of assignment,
// C knows that you mean pointer, and you don't need explicit &
operation = add;
}
Similarly, an array is also not a variable in C. You can make up a similar example as above and test out.