Problem with storing pointer

Hi all,

I have a void pointer (args) and I want that pointer to point to a function pointer. I have this:
1
2
3
4
5
6
Thread(void (*workerFunction)())
{
	args = new void*; //Create space to store a function pointer
	*args = workerFunction; //Store the function pointer
	startThread(realWorkerFunction0);
}

But I get errors like "Illegal indirection" at line 4 (of this code block). As you can see this is a constructor. Line 5 is not really of concern here.

What am I doing wrong and how can I get the job done?

Thanks you :)
Last edited on
I got a work-around at the moment but I still want to figure this out ;)
Why don't you just declare another function pointer to store workerFunction in?
I would have an extra variable in the class, which is a bit less efficient. ;)
I have to say that the idea of bunging different types of values into a void* just to save a little space is a tinsy-winsy bit frightening...
Well actually, I have 127 different constructors which create a struct to store on the heap, thats where args point to, but since this constructor creates a struct which only contains the function 'workerFunction', I wanted to skip the creation of the struct, to produce a bit less code. So I'm not 'bunging different types of values into a void*' to save tinsy-winsy space, but to save 127 object of incremental size.
Last edited on
Okay. I don't fully understand what you're doing there but I'm still scared... ;o)
What I'm actually are doing: I'm creating a class named Thread which support up to 127 arguments which you can pass to you worker function. But it wasn't really related to my question :P
True.

Well despite the fact that this web-site is called "Safer Code" nothing on this following page is particularly safe:

http://www.safercode.com/blog/2008/11/25/generic-function-pointers-in-c-and-void.html
Ok thanks. As that isn't really safe, I'll stick with my implementation which I callad a work-around earlier. Anyway, I also tried this:
1
2
args = new (void (*)());
(void (*)())(*args) = workerFunction;

But that doesn't work neither.
The problem is that a void* can be smaller than a function pointer on some systems.

Its probably better to use a union like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
union stuff
{
    my_usual_struct* sp;
    (void)(*fp)();
};

stuff args;

// store a struct
args.sp = new my_usual_struct;

// store a function pointer
args.fp = workerFunction


There is almost always a better way of doing things than resorting to these tactics.
Yeah, but what if the size of "void (*)()" is bigger or smaller than normal pointers? I don't think that would be a good idea.
That's the whole point about using a union. Its as big as its largest member and no bigger. It solves the problem of unequal sized pointers without taking up additional space.
void * is as big as the largest possible data pointer. Otherwise, it would be completely useless as a generic pointer.

The fact that function pointers can be larger than data pointers is but the tip of a massive iceberg.
Function pointers also hold (at compile time) the pointed function's calling convention as type information. This is to keep you from doing stupid things like
1
2
3
4
5
//Pretend I used the calling convention syntax right, although I probably didn't.
typedef void __cdecl (*fp)();
void __stdcall f();
fp p=(fp)f; //Correct return type, correct function signature, but wrong calling convention.
p();    //Enjoy your corrupted stack! 

Now, this is not a problem if you're consistent with your calling conventions. The real problem is when a function in a dynamic library takes a callback pointer and the dumbass user forgets to read the damn documentation.
And let's not get into the whole problem of member function pointers.
There's simply no such thing as a "generic function pointer". Explicitly cast function pointers at your own peril.

PS: Note that in any system that implements Windows' GetProcAddress() or UNIX's dlsym() (both necessary for dynamic linking, which makes any system that doesn't implement them, virtually useless), it's safe to cast function pointers to void *. Whether it's safe to cast this to a given function pointer type and call that, is a different matter.
Last edited on
void * is as big as the largest possible data pointer. Otherwise, it would be completely useless as a generic pointer.

Yes, I knew that, but my concern was actually that I'm not sure if that's safe. Can you be sure that the converted void pointer contains valid data of that function pointer?
Last edited on
Oh. Disregard the first paragraph. I misread "void (*)()" as "void *", for some reason.

Like I said, void * is big enough to point to any regular function on Windows and UNIX systems. You can check that using predefined macros. The real problem is casting the pointer back to the correct type.

Why exactly do you want to do this, anyway? What's wrong with the traditional method of passing generic pointers to structures? It's easy to implement, hard to screw up, and it works everywhere.
Why exactly do you want to do this, anyway?

I thought it would be easier. :P
What's wrong with the traditional method of passing generic pointers to structures? It's easy to implement, hard to screw up, and it works everywhere.

I think that what you mean is that I put the function pointer in a struct and point to that struct instead to the function pointer, that's what I did eventually.
Last edited on
Uh... No.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void function_with_callback(void (*f)(void *),void *data){
    f(data);
}

struct A{
    //...
};

void f(void *p){
    A *data=(A *)p;
    //...
}

A a;
function_with_callback(f,&a);
Topic archived. No new replies allowed.