Use case of function pointers in c - c

One of the common use cases I've come across when I read about function pointers is that they can be used to make a function more flexible, as part of the functionality of the function can be taken in as a parameter. An example for this is qsort where I can make a compare function to decide what is meant by greater and lesser (ascending, descending, is a multiple of,etc) and pass the compare funtion pointer to qsort function.
Here, the function repeat has addptr as parameter and therefore performs multiplication.
int add(int a, int b)
{
return a+b;
}
int (*addptr)(int,int);
int repeat(int a,int b,int (*funcptr)(int,int))
{
int i,ans=0;
for(i=0;i<a;i++)
{
ans=(*funcptr)(ans,b);
}
return ans;
}
int main()
{
addptr=&add;
printf("%d\n",repeat(7,5,addptr));
return 0;
}
But the same exact thing can be done without function pointers at all!
int add(int a, int b)
{
return a+b;
}
int repeat(int a,int b,int func(int,int))
{
int i,ans=0;
for(i=0;i<a;i++)
{
ans=func(ans,b);
}
return ans;
}
int main()
{
printf("%d\n",repeat(7,5,add));
return 0;
}
So why is this even one of the uses of function pointers?
What is the advantage of the first code over the second?

There is a rule C11 6.7.6.3/8 saying that if you write a function inside a parameter list, it will get adjusted to a pointer to function of that type:
A declaration of a parameter as ‘‘function returning type’’ shall be
adjusted to ‘‘pointer to function returning type’’,
This works similar to when you write an array as function parameter, it gets adjusted to a pointer to the first element.
That being said, it is not really meaningful to write a function as a parameter, it is just very confusing to the reader. Use function pointers instead.
EDIT
For maximum readability, I would personally recommend using this style:
typedef int operation_t (int, int);
int repeat (int a, int b, operation_t* operation)
{ ...
Though the most commonly used style is perhaps this one:
typedef int (*operation_t) (int, int);
int repeat (int a, int b, operation_t operation)
{ ...
I prefer the former since hiding pointers behind typedefs is a bad idea, and since that style makes function pointers consistent with regular pointers.

As noticed in comment by #user2390668, func in repeat in already a function pointer. And when you call it, add decays to a function pointer.
If your question is what is a possible use case for a variable holding a function pointer, we must try to imagine a use case where a function will not only be passed as a parameter, but will have to be stored. An example for that would be simulating polymorphism of structs in C. Here is an oversimplified example:
#include <stdio.h>
struct Base {
/* common member variables
...
*/
const char *name;
void (*display)(void *, FILE *fd);
};
struct S1 {
struct Base base;
/* other member variables */
};
void _S1_display(void *this, FILE *fd) {
struct S1 *s1 = this;
fprintf(fd, "In S1, name: %s\n", s1->base.name);
}
struct S2 {
struct Base base;
/* other member variables */
};
void _S2_display(void *this, FILE *fd) {
struct S2 *s2 = this;
fprintf(fd, "In S1, name: %s\n", s2->base.name);
}
void process(void *this, FILE *fd) {
struct Base *base = this; /* valid because base is first element of both S1 and S2 */
base->display(this, fd);
}
int main() {
struct S1 s1 = { "s1", &_S1_display };
struct S2 s2 = { "s2", &_S2_display };
process(&s1, stdout);
process(&s2, stdout);
return 0;
}
Ok, fur such a simply example, polymorphism would not be necessary, but as I said it is oversimplified...

You may use pointers to functions when you need a little more abstraction.
For example, you may want to manage a table of operators that a generic function should use:
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mult(int a, int b) {
return a*b;
}
int div(int a, int b) {
return a/b;
}
void doit(int a,int b,int (*ptr[2])(int,int)) {
printf("%d\n",ptr[0](a,b));
printf("%d\n",ptr[1](a,b));
}
int main() {
int (*ptr[2])(int,int);
printf("additives (1) or multiplicatives (2) ?");
int choice;
scanf("%d",&choice);
switch(choice) {
case 1:
ptr[0] = &add;
ptr[1] = ⊂
break;
default:
ptr[0] = &mult;
ptr[1] = &div;
break;
}
doit(7,5,ptr);
return 0;
}
Of course you can also design a doit function with two pointers but sometimes a table is more convenient (think about a variable length table of function pointers for example, I know even in this case we may use a variable arguments list...).
At least, passing a function pointer in parameter is defining a function pointer variable...
Another example is also implementing in C object oriented programming, where you may implement methods as function pointers members.

Related

Call a function using a pointer and pass the pointer that can point to the function along in the parameters

Say that I have a pointer to function theFunc. theFunc takes along a pointer that can point to any function with the same parameter list as theFunc, so the function called can set the passed pointer to NULL or a different function.
Using it would look like this:
while (funcPtr != NULL)
{
funcPtr(&funcPtr);
}
Would defining this be impossible?
Yes, it's doable.
The simple way:
void (*fptr_t)(void*);
The function pointer is data, even though it point to non-data. Therefore a pointer to function pointer can be converted to void* without relying on compiler extensions.
This solution lacks type safety. However, it can be improved.
Currently, it is possible to declare a function taking unspecified number of parameters. It allows to form an incomplete function type. For example:
int foo();
declares a function that returns int and takes unspecified parameters. To have a function taking no parameters use int foo(void).
This allows to declare a function taking a pointer to pointer to incomplete function type:
int foo(int (**)());
// call
int (*fptr)(int (**)()) = foo;
fptr(&fptr);
As mentioned in other answers typedef-ing function types makes the code cleaner.
typedef int foo_aux_f();
typedef int foo_f(foo_aux_f**);
foo_f *fptr = &foo;
fptr(&fptr);
It is possible to improve type safety by nesting the declaration of function types deeper and deeper.
typedef int foo_aux0_f();
typedef int foo_aux1_f(foo_aux0_f**);
typedef int foo_aux2_f(foo_aux1_f**);
typedef int foo_aux3_f(foo_aux2_f**);
typedef int foo_f(foo_aux3_f**);
foo_f fptr = &foo;
fptr(&fptr);
The perfect recursive type would be reached with infinite chain of declaration but in practice 2-3 levels are sufficient.
With some abuse of the syntax of typedef keyword it is possible to squeeze the declaration of this type:
typedef int foo_aux0_f(),
foo_aux1_f(foo_aux0_f**),
foo_aux2_f(foo_aux1_f**),
foo_aux3_f(foo_aux2_f**),
foo_f(foo_aux3_f**);
Unfortunately ... or fortunately, this trick will likely not work in upcoming C23 because the old function declarations without prototypes are planned to be removed from the language making () mean no arguments rather then unspecified number of argument.
Yes, you can pass pointer to pointer to function. The syntax is much easier if you use typedefs.
typedef void somefunc(void);
void func1(void)
{
printf("Func1\r");
}
void func2(void)
{
printf("Func2\r");
}
void swapfunction(somefunc **ptr)
{
if(*ptr == func1) *ptr = func2;
else *ptr = func1;
}
int main(void)
{
somefunc *ptr = NULL;
swapfunction(&ptr);
ptr();
swapfunction(&ptr);
ptr();
}
You can also use function return value:
typedef void somefunc(void);
void func1(void)
{
printf("Func1\r");
}
void func2(void)
{
printf("Func2\r");
}
somefunc *swapfunction(somefunc *ptr)
{
if(!ptr) return func1;
else if (ptr == func1) return func2;
else return NULL;
}
int main(void)
{
somefunc *ptr = NULL;
while(ptr = swapfunction(ptr))
{
ptr();
}
}
Ref your github comment, suggest you use a structure instead of type casting pointers to function pointers, etc. It's not exactly what you are requesting, but kind of.
The code will then look like:
#include <stdio.h>
struct funcArgStruct
{
void (*state)(struct funcArgStruct *);
// int extra_data; // optional
};
typedef struct funcArgStruct funcArg;
void start (funcArg *ptr);
void task1 (funcArg *ptr);
void stop (funcArg *ptr);
/* Implementation of an fsm. */
int main()
{
funcArg ptr_, *ptr = &ptr_;
ptr->state = start;
// ptr->extra_data = 0; // optional
while (ptr->state != NULL)
{
ptr->state(ptr);
}
return 0;
}
void start (funcArg *ptr)
{
ptr->state = task1;
}
void stop (funcArg *ptr)
{
ptr->state = NULL;
}
void task1 (funcArg *ptr)
{
ptr->state = stop;
}
This sort of works:
#include <stdio.h>
void *a(void)
{
printf("Calling a()\n");
return NULL;
}
void *b(void)
{
printf("Calling b()\n");
return a;
}
void *c(void)
{
printf("Calling c()\n");
return b;
}
int main(void)
{
void *(*funcPtr)(void) = &c;
while (funcPtr) {
funcPtr = funcPtr();
}
}
I don't really see good uses, especially in passing the pointer to the function itself as an argument (which I why I omitted it) but whatever floats your boat. You can of course replace the arguments to whatever you need.
You could add a typedef to help out a bit with a type:
typedef void *(*myfunc)(void);
Then you could do the following:
myfunc funcPtr = &c;
// instead of: void *(*funcPtr)(void) = &c;
I don't think any of this is particularly elegant, but it should work.
Note that it doesn't matter if you assign c or &c to myfunc, or whether you return a or &a from one of the functions.

Merging two similar c functions into one

I have two functions that look like the ones down below and I am trying to merge the two with a function called function3 however I don't want it to check the parameter 'function' everytime it enters the while loop as it is a very poor way to do it. I am wondering if I can merge the two with only one if statement.
void function1(){
int value,a,b;
while(condition){
value=a*b;
}
}
void function2(){
int value,a,b;
while(condition){
value=a+b;
}
}
//merge two functions
void function3(int function){
int value,a,b
while(condition){
if(function==1){
value=a*b;
}
else{
value=a+b;
}
}
}
It is not clear from the code you posted what you intent to do, since you don't actually do anything with the values you calculated.
Aside, I think that you are looking for an array of functions or an array of pointers to functions.
You can use the variable function to access the function that you need, assuming it matches the array index of that function.
int function1(int a, int b) {
return a * b;
}
int function2(int a, int b) {
return a + b;
}
int (*f[])(int, int) = { function1, function2 };
void call_function(int function, int a, int b) {
// check that "function" is within bounds of the array
if (function < 0 || function >= sizeof(f) / sizeof(f[0])) {
// handle out of bounds
}
// call appropriate function
int ret_val = f[function](a, b);
return;
}

How to pass structure field name to function?

I have many similar function calls dealing with one structure, but each call is using different field of structure.
Example:
typedef struct {
int i1;
int i2;
int i3;
} S;
functions to get structure fields (it would be better to avoid them):
int getFieldI1 (S *s){ return s->i1; }
int getFieldI2 (S *s){ return s->i2; }
int getFieldI3 (S *s){ return s->i3; }
function i have to call many times:
void doJob (int (*get_field_func)(S *)){
//some code
S s;
int v = get_field_func(&s);
//some code
}
i call doJob() this way:
doJob(&getFieldI1);
doJob(&getFieldI2);
doJob(&getFieldI3);
i would like to do like this:
doJob(i1);
doJob(i2);
doJob(i3);
is it possible in C?
option 1 - offsets
You can use memory offsets.
void doJob (int offset){
//some code
S s;
int v = *(&s+offset*sizeof(int));
//some code
}
You can call it like this:
doJob(0);//i1
doJob(1);//i2
doJob(2);//i3
As pointed out in the comments, the offsets are unsafe. You can create a check for this:
if(offset>2||offset<0){
//some kind of error
}
Also, this can only be used if the structure only contains integers(or elements of the same type, you would need to adjust it)(see comments).
If there are elements before s1, s2 and s3, you'll need to add the size of the elements(as padding, just add it);
option 2 - constants
Another option (that hasn't the mentioned problems) is to define constants/macros:
You'll just define them like this:
#define I1 &getFieldI1
#define I2 &getFieldI2
#define I3 &getFieldI3
and just call it using:
doJob(I1);
doJob(I2);
doJob(I3);
Just pass in a pointer to the field:
void doJob( int* fieldPointer )
{
assert( fieldPointer != NULL );
// Get the field value:
int v = *fieldPointer;
// Do something with the field value:
v += 10;
// Save the updated value back to the field:
*fieldPointer = v;
}
Usage:
S structInstance = ...
doJob( &structInstance.i1 );
doJob( &structInstance.i2 );
doJob( &structInstance.i3 );
How to pass structure field name to function?
In general, you cannot. A typical library coded in C does not show fields of internal struct to outside. In other words, a field name is only known to the compiler, and relevant to the current translation unit, and makes no sense at runtime.
Consider the following metaprogramming approach: write a metaprogram (in C or in some scripting language like Guile, awk, Python, etc...) generating your C code, and set up your build accordingly. That might mean to edit your Makefile, or configure your build automation tool.
This is usual practice since the previous century. Look into SWIG or RPCGEN as a famous example.
You might perhaps use preprocessor tricks, e.g. X-macros.
Unfortunately, C doesn't allow exactly what you need. But you can achieve a partial win with some code changes.
I have one and half solutions. For the first I propose a (simplified!) implementation, for the second I provide just an hint. Please, check if they can be acceptable for you.
Your example structure:
typedef struct {
int i1;
int i2;
int i3;
} S;
I would define an enum representing the specific field:
typedef enum
{
FIELD_ID_I1,
FIELD_ID_I2,
FIELD_ID_I3,
FIELD_ID_MAX
} FieldId_e;
Then I would add a field parameter in your general function, managing internally the correct field to be returned. Some smart error managing in case of wrong ID has to be done here. I just return -1 for brevity.
int getField (S *s, FieldId id)
{
int ret = -1;
switch(id)
{
case FIELD_ID_I1:
ret = s->i1;
break;
case FIELD_ID_I2:
ret = s->i2;
break;
case FIELD_ID_I3:
ret = s->i3;
break;
}
return ret;
}
Your doJob will become
void doJob (int (*get_field_func)(S *, FieldId), FieldId id){
//some code
S s;
int v = get_field_func(&s, id);
//some code
}
And final call will become this one. But probably (and it depends on your scenario) having a single general function will make possible to omit the function pointer, simplifying much the interface.
doJob(&getField, FIELD_ID_I1);
doJob(&getField, FIELD_ID_I2);
doJob(&getField, FIELD_ID_I3);
Just a short reference to another tricky solution that would require to play with pointers.
Do you know offsetof macro? (Wikipedia EN)
It evaluates to the offset (in bytes) of a given member within a
struct or union type, an expression of type size_t. The offsetof()
macro takes two parameters, the first being a structure name, and the
second being the name of a member within the structure.
In this case you could have something like
int getField (S *s, size_t offset);
doJob(&getField, offsetof(S, i1));
I failed to guess right types for i1/i2/i3, sorry. So I use auto keyword from c++:
#include <stdio.h>
typedef struct {
int i1;
int i2;
int i3;
} S;
int getFieldI1 (S *s){ return s->i1; }
int getFieldI2 (S *s){ return s->i2; }
int getFieldI3 (S *s){ return s->i3; }
void doJob (int (*get_field_func)(S *)){
//some code
S s = {1,2,3};
//S s;
int v = get_field_func(&s);
//some code
printf("got: %d\n", v);
}
int main() {
S s = {1,2,3};
auto i1 = getFieldI1;
auto i2 = getFieldI2;
auto i3 = getFieldI3;
doJob(i1);
doJob(i2);
doJob(i3);
}
Then
g++ 59503102.cxx -o 59503102 && ./59503102
as expected produces
got: 1
got: 2
got: 3
plain c version
#include <stdio.h>
typedef struct {
int i1;
int i2;
int i3;
} S;
int getFieldI1 (S *s){ return s->i1; }
int getFieldI2 (S *s){ return s->i2; }
int getFieldI3 (S *s){ return s->i3; }
void doJob (int (*get_field_func)(S *)){
//some code
S s = {1,2,3};
//S s;
int v = get_field_func(&s);
//some code
printf("got: %d\n", v);
}
int main() {
S s = {1,2,3};
int (*i1)(S *) = getFieldI1;
int (*i2)(S *) = getFieldI2;
int (*i3)(S *) = getFieldI3;
doJob(i1);
doJob(i2);
doJob(i3);
}

Is it possible to swap C functions?

Looking to see if anyone knows if its possible to swap C functions...?
void swap2(int(*a)(int), int(*b)(int)) {
int(*temp)(int) = a;
*a = *b;
*b = temp;
// Gives 'Non-object type 'int (int)' is not assignable
}
swap2(&funcA, &funcB);
EDIT
More data here as to intention -- Some answers have been provided below which do work such as creating the function ptr using typedef, pointing them to the functions and switching those, which lets you invoke the new swapped ptrs successfully.
BUT calling the functions by their original names after swapping shows no change. Essentially I'm looking for a c equivalent of the objc "swizzle".
I'm beginning to think this isn't possible, due to c's complete lack of reflection, and would require actually modifying the binary itself (obviously not feasible). D:
Comments welcome.
If you use the function pointers like below, it is yes
typedef int (*func_pt)(int);
func_pt a, b;
void swap(func_pt * a, func_pt * b)
{
func_pt tmp = *b;
*b = *a;
*a = tmp;
}
swap(&a, &b);
Or you use it as this, I think it is no:
int test1(int a)
{
return a;
}
int test2(int b)
{
return b;
}
swap(&test1, &test2);
Complete compiling working program
#include <stdio.h>
#include <stdlib.h>
typedef int (* func_pt)(int);
func_pt a, b;
int test1(int a)
{
printf("test1\n");
return 1;
}
int test2(int a)
{
printf("test2\n");
return 2;
}
void swap(func_pt * a, func_pt * b)
{
func_pt tmp = *b;
*b = *a;
*a = tmp;
}
int main(void)
{
a = &test1;
b = &test2;
printf("before\n");
a(1);
b(1);
swap(&a, &b);
printf("after\n");
a(1);
b(2);
return 0;
}
Output:
before
test1
test2
after
test2
test1
Some people do not try it by themselves, just say it absurd.So I give you a example.
I'm pretty sure you need pointers to function pointers to swap pointers, no? This type of swapping function swaps values; you really want to deal in addresses. The example function call wouldn't really work because C doesn't treat functions as first-class variables so you can't actually swap functions directly; you need to use pointers to function addresses, since addresses CAN be swapped:
void swap2(int(**a)(int), int(**b)(int)) {
int(*temp)(int) = *a;
*a = *b;
*b = *temp;
}
int(*func1)(int) = &foo;
int(*func2)(int) = &bar;
swap2(&func1, &func2);
Your code will give error like "invalid lvalue" at the time of assignment. As I can see in your code you are trying to swap pointers without changing its values so have a look on below solution.
void swap2(int(**a)(int), int(**b)(int)) {
int(*temp)(int) = *a;
*a = *b;
*b = temp;
}
int main(){
int(*temp1)(int) = &funcA;
int(*temp2)(int) = &funcB;
swap2(&temp1,&temp2);
}
Yes,you can. Think that a function-pointer is just a memory-address,the single requeriment is: where you will keep such address needs to be mutable. Say,int (*foo)() not really to where foo points to. May be to printf() or fopen().
Although the subject asks about swapping functions, you actually want to emulate what swizzle does. This just means you want to be able to call the same function name but have it do something different.
A pointer only solution will not give you that behavior. If that is not important to you, then you should adopt one of the function pointer only solutions provided. If it is important to you, then, you will need to introduce a layer of abstraction. The abstraction could use function pointers under the hood (although there are other solutions).
The API to users of this interface would be:
/* API to initialize */
void abstract_func_init ();
/* API to manipulate abstract functions */
typedef int abstract_func_type ();
abstract_func_type * abstract_func_get (abstract_func_type *key);
int abstract_func_set (abstract_func_type *key, abstract_func_type *behavior);
/* the abstract functions */
extern int foo ();
extern int bar ();
The implementation of such an interface could look like:
static void insert (abstract_func_type *key, abstract_func_type **behavior)
{ /* associate key to behavior */ }
static abstract_func_type ** lookup (abstract_func_type *key)
{ /* return behavior from key */ }
abstract_func_type * abstract_func_get (abstract_func_type *k) {
abstract_func_type **f = lookup(k);
if (f) return *f;
return 0;
}
int abstract_func_set (abstract_func_type *k, abstract_func_type *p) {
abstract_func_type **f = lookup(k);
if (f) {
*f = p;
return 0;
}
return -ENOENT;
}
#define DEFINE_ABSTRACT_FUNC(func) \
static int static_##func (); \
static abstract_func_type *func##_ptr = static_##func; \
int func () { return func##_ptr(); } \
static int static_##func ()
DEFINE_ABSTRACT_FUNC(foo) { return puts("foo"); }
DEFINE_ABSTRACT_FUNC(bar) { return puts("bar"); }
void abstract_func_init () {
insert(foo, &foo_ptr);
insert(bar, &bar_ptr);
}
Then, the swap() you initially presented in your post could be implemented like this:
void swap (abstract_func_type *a, abstract_func_type *b) {
abstract_func_type *ap = abstract_func_get(a);
abstract_func_type *bp = abstract_func_get(b);
abstract_func_set(a, bp);
abstract_func_set(b, ap);
}
Here is a program that calls swap():
puts("before swap");
foo();
bar();
swap(foo, bar);
puts("after swap");
foo();
bar();
And its output would be:
before swap
foo
bar
after swap
bar
foo
To automate the adding of abstract functions into the lookup table, you could introduce into the build system an extra step that called a script that would grep out the DEFINE_ABSTRACT_FUNC lines, and generate a new source file that had a function with the calls to insert() for each such line.
A complete version of the mock-up can be found here.

How to create a typedef for function pointers

I think it would be easier to use function pointers if I created a typedef for a function pointer, but I seem to be getting myself tripped up on some syntax or usage or something about typedef for function pointers, and I could use some help.
I've got
int foo(int i){ return i + 1;}
typedef <???> g;
int hvar;
hvar = g(3)
That's basically what I'm trying to accomplish I'm a rather new C programmer and this is throwing me too much. What replaces <???> ?
Your question isn't clear, but I think you might want something like this:
int foo(int i){ return i + 1;}
typedef int (*g)(int); // Declare typedef
g func = &foo; // Define function-pointer variable, and initialise
int hvar = func(3); // Call function through pointer
You are right. The function pointer can be conveniently used to point to the different functions of the same return type and taking same number of arguments.
The argument types should match the declaration of the function pointer arguments.
In your case you could define your function pointer g as:
typedef int (*g)(int); // typedef of the function pointer.
g is a function pointer for the function returning int value and taking one int argument.
The usage of function pointer could be illustrated by a simple program below:
#include<stdio.h>
typedef int (*pointer_to_function)(int first_parameter_of_type_int, int second_parameter_of_type_int);
int my_function_returning_int_and_taking_two_int_arguments(int par1, int par2)
{
int result = par1 + par2;
return result;
}
int my_mul_function(int par1, int par2)
{
int result = par1 * par2;
return result;
}
int main()
{
int res; // returning result will be here
pointer_to_function my_fun_pointer; // declare function pointer variable;
my_fun_pointer = my_function_returning_int_and_taking_two_int_arguments; // function pointer points to `my_function_returning_int_and_taking_two_int_arguments` function
res = my_fun_pointer(2,3); // Call function through pointer
printf(" result of `my_function_returning_int_and_taking_two_int_arguments` = %d \n", res);
my_fun_pointer = my_mul_function; // now function pointer points to another function: `my_mul_function`
res = my_fun_pointer(2,3); // Call function through pointer
printf(" result of `my_mul_function` = %d \n", res);
return 0;
}
OUTPUT:
result of `my_function_returning_int_and_taking_two_int_arguments` = 5
result of `my_mul_function` = 6
The original way of writing the function returning function pointer is
int (* call(void) ) (int,int);
Here call is a function which takes nothing but returns a function pointer which takes 2 arguments and returns an integer value. Pay attention to the brackets, they are absolutely necessary.
Here is the code:
#include<stdio.h>
int sum(int a,int b) //sum is the function returned by call
{
return a+b;
}
int (*call(void) ) (int ,int);
int main() {
int (*p)(int,int); // way to declare a function pointer
p=call();
printf("%d\n",(*p)(8,3));
}
int( *call(void) )(int,int) {
return sum;
}

Resources