10 Mar, 2010, JohnnyStarr wrote in the 1st comment:
Votes: 0
Because I need some sort of polymorphism when hooking into Lua, I have considered using void* pointers
as parameters to my call_lua(…) function. From what I've read this can be an inefficient use of memory.
Is this true? If so, can you explain why?

Because each call to lua may require 1 or more objects, would it just be better to construct a container
of pointers to these objects, then send in the head pointer to this container? Just an idea anyway.
10 Mar, 2010, Kline wrote in the 2nd comment:
Votes: 0
Last time I ever tried to do something where I figured void pointers were easiest, I had a lot of things yelling at me for casting things back and forth. That, and someone suggested a union of just the types you'll ever require, instead.
10 Mar, 2010, David Haley wrote in the 3rd comment:
Votes: 0
Where did you read that it's an inefficient use of memory? It depends on what you're doing. If you're storing chars, then yes using a void pointer that points to a char is wasteful (3 or 7 bytes depending on various things). (EDIT: Sometimes, you have no choice.)

Sometimes you don't have the option of using a union, like when interfacing with Lua for example, or in general when having general user data pointers to data types that you don't know about. (This is a very common situation for callback libraries.)
Anyhow Lua doesn't know about your types in the first place, so it wouldn't understand your type union; it would only understand void*.
11 Mar, 2010, JohnnyStarr wrote in the 4th comment:
Votes: 0
David Haley said:
Where did you read that it's an inefficient use of memory?

I was googling and found this.
I had considered a union, but came to the same conclusion. I was searching my code base for some uses of void * and stumbled on the "act" routine.
void act (const char *format, CHAR_DATA *ch, const void *arg1, const void *arg2, int type)

It's signature uses voids and works quite well. I am just trying to avoid writing hackish code, and because my knowledge of C is at an intermediate stage,
I would like to continue to learn the "right" way.
11 Mar, 2010, Runter wrote in the 5th comment:
Votes: 0
The only reason they would be considered less efficient is because you would possibly need overhead to determine what it actually points to instead of it being baked in. This isn't necessarily true. It may just so happen that other indicators of what the void pointer is already exist. In any event, I wouldn't use a void pointer unless I had to.
11 Mar, 2010, David Haley wrote in the 6th comment:
Votes: 0
The "right" way to use void* is when you really don't know what kind of type might be coming in. A very classic example of this is callback functions where you can supply userdata to those callbacks. For example,

register_mouse_callback(my_mouse_function, &my_app_state);


The mouse handler library function "register_mouse_callback" takes as arguments two things: (1) a function and (2) user data to pass to that function. Let's take a look at how my_mouse_function might be defined:

void my_mouse_function(int x, int y, void* userdata) {
AppState* state = (AppState*) userdata;
state->mouseX = x;
state->mouseY = y;
}


The event handler library really has no idea what kind of data you might find useful to pass to the mouse callback. So, it lets you pass in whatever the heck you want, on the assumption that you won't screw up in your callback and will handle the void* appropriately. In this case, we know that the callback is only called when the void* points to an AppState, so we can safely cast it.

There are other places you might use a void*, like what Runter alluded to where you have a type indicator alongside the void*. This is a common technique for implementing dynamic features where you can switch on the type indicator and do the right thing with the pointer. (This is one way to implement OOP in straight C, for example. Not necessarily the best way, but a way.)
The 'act' function does something like this. It relies on the contents of the format string to tell it what the void* is. If the format string uses $o (or whatever it is), the code knows that the void* must point to an object. (etc.)
0.0/6