Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function pointers within a struct but with functions of different prototype in C

Suppose I have functions:

void func1(int x)
{
    ....
}

void func2(int x, int y)
{
    ....
}

void func3(int x, int y, int z)
{
    ....
}

And say that I want to have a function pointer within a struct:

For example

typedef struct{
     char *ename;
     char **pname;
    < and here I want to have a function pointer> ??
} Example;

Example ex[3];

Now, I want to populate the ex[3] array as:

ex[0].ename = "X0";
ex[0].pname[0]="A0";
ex[0].pname[1]="B0";
ex[0].<function pointer to func1() > ??


ex[1].ename = "X1";
ex[1].pname[0]="A1";
ex[1].pname[1]="B1";
ex[1].<function pointer to func2() > ??

... and so on...

Is it possible to create something like this? Please help me with this. Thanks.

like image 590
user1128265 Avatar asked Mar 02 '12 15:03

user1128265


People also ask

Can you have a function pointer in a struct?

Function pointers can be stored in variables, structs, unions, and arrays and passed to and from functions just like any other pointer type. They can also be called: a variable of type function pointer can be used in place of a function name.

What is the prototype of a function pointer?

In sum, a function pointer declaration looks exactly like a standard function prototype, with the exception of the (*name) structure where the prototype would just have the function name.

Can structs have functions in C?

Member functions inside the structure: Structures in C cannot have member functions inside a structure but Structures in C++ can have member functions along with data members.


2 Answers

I would use a union of function pointers:

union {
    void (*fun1)(int);
    void (*fun2)(int, int);
} fptr;

You also need a field in the struct to tell which is used.

like image 122
cnicutar Avatar answered Nov 14 '22 22:11

cnicutar


You have two choices - sloppy but easy, or exact but painstaking.

Sloppy

typedef struct{
     char *ename;
     char *pname[3];
     void (*function)();   // Pointer to function taking indeterminate arguments
} Example;

Example ex[3] =
{
    { "func1", { "x",           }, func1 },
    { "func2", { "x", "y",      }, func2 },
    { "func3", { "x", "y", "z", }, func3 },
};

This doesn't pass muster if you compile with -Wstrict-prototypes in GCC. Notice that I made sure there was storage for the parameter names - your original had char **pname which would mean you have to allocate the storage for the arrays before assigning the names.

Painstaking

typedef struct{
     char *ename;
     char *pname[3];
     union
     {
         void (*f1)(int x);
         void (*f2)(int x, int y);
         void (*f3)(int x, int y, int z);
     } u;
} Example;

Example ex[3] =
{
    { "func1", { "x",           }, .u.f1 = func1 },
    { "func2", { "x", "y",      }, .u.f2 = func2 },
    { "func3", { "x", "y", "z", }, .u.f3 = func3 },
};

This uses C99 designated initializers to do the initializing. It assigns each function pointer to the correctly typed element of the union.

like image 40
Jonathan Leffler Avatar answered Nov 14 '22 21:11

Jonathan Leffler