views:

71

answers:

2
struct a
{
  int (*ptr1)();
  int (*ptr2)();
  int data;
};

typedef struct
{
  struct a x;
}all;

int fun1()
{
  return 5;
};

int fun2()
{
  return 9;
};

I can assign like

all *mem = (all*)malloc(sizeof(all));

mem->x.ptr1 = fun1;
mem->x.ptr2 = fun2;

Is there any other way to assign these function pointers? Is it possible to assign like this?

all *mem;

(void **)mem->ptr1[0] = fun1; 
(void **)mem->ptr2[1] = fun2;
+3  A: 

No, this is not possible (I assume you actually meant the following, since your code doesn't make much sense)

((void **)&mem->ptr1)[0]=fun1;
((void **)&mem->ptr1)[1]=fun1;

This is syntactically correct, but quoting the C standard:

There may be unnamed padding within a structure object, but not at its beginning.

which means you are not guaranteed that ((void **)&mem->ptr1)+1 == ((void **)&mem->ptr2).

The statement you posted

(void **)mem->ptr1[0] = fun1;

actually means

(void **)((mem->ptr1)[0]) = fun1;

which tries to index a function-pointer.

Note that all references like mem->ptr1 etc. should actually be mem->x.ptr1 according to your definitions.

jpalecek
+1  A: 

No, you can't assign like this for many reasons:

  1. function pointers are not compatible with void*. your compiler may allow this but this is undefined behavior according to the standard
  2. By using [0] and [1] you are doin't pointer arithmetic on a void pointer, which isn't allowed either.

Also in your first example which works, you assign a pointer to a function. This is ok as you did, since a function if you don't put () after it evaluates to its address. But still I find it clearer to write &f in such case.

Jens Gustedt