Home > Software engineering >  C: what is a void* besides a pointer?
C: what is a void* besides a pointer?

Time:07-11

Reading CMU's OS Course Home Page, they say:
"It is a good idea to be familiar with C conventions. For example, it is not generally the case that a void * is a pointer. If seeing a void * parameter, or a void ** parameter, in a function prototype would be confusing, this would be a good area to look into."

I honestly have no idea what they mean by this, what is a void * if not a pointer?

CodePudding user response:

One case where void * is not a pointer involves passing data to a callback function. Imagine some library gives you a function which does some useful work, and calls your function (callback) in the middle of that work.

// useful_header.h
int do_useful_work(int data1, int data2, int (*callback)());

You call this function like this:

// your_code.c
int my_callback()
{
    ...
    return 42;
}

int main()
{
    int useful_result = do_useful_work(2, 3, my_callback);
}

What if you want to pass data to your callback? The company which provides do_useful_work doesn't know which data your callback wants to get. So it provides the most generic thing - void *. Your callback interprets it as a pointer to your struct.

// useful_header.h
int do_useful_work(int data1, int data2, int (*callback)(void *), void *user_data);

// your_code.c
struct MyData
{
    int x, y, z;
};

int my_callback(void *pointer)
{
    struct MyData *data = pointer;
    ...
    return data->x   data->y   data->z   42;
}

int main()
{
    struct MyData data = {5, 6, 7};
    int useful_result = do_useful_work(2, 3, my_callback, &data);
}

This has an edge-case: what if your callback wants to receive only a small item (of type int), and not a whole struct? Then you could interpret the pointer as int.

// your_code.c
int my_callback(void *not_really_pointer)
{
    int data = (int)not_really_pointer;
    ...
    return data   42;
}

int main()
{
    int useful_result = do_useful_work(2, 3, my_callback, (void *)5);
}

Here, the void * argument is not really a pointer - it's a number, which is passed using void * type because C enforces type-checking.

Having said that, this is an example of sloppy coding; making a struct with one element would be clearer here.

  •  Tags:  
  • c
  • Related