开发者

Using void * in C in place of overloading?

My question here is I had seen code like this for a multithreading application:

void Thread( void* pParams )
{  
    int *milliseconds = (int *)pParams;
    Sleep(milliseconds);
    printf("Finished after %d milliseconds", milliseconds); //or something like that
}

This greatly took my interest, I knew malloc sends back a void pointer and you can cast it to what you want, does this mean that I can create a function that can accept any data type?

For example a function I wrote without testing:

void myfunc( void* param )
{  
    switch(sizeof(param)) {
       case 1:
       char *foo = (char *)param; break;
       case 2:
       short *foo = (short *)param; break;
       case 4: 
       int *foo = (int *)param; b开发者_如何学Creak;
    }
}
myfunc(3.1415);
myfunc(0);
myfunc('a');

I may be completely wrong, even if this does work is it horrible practise? Thanks.


yes, void * is great for the creation of generic functions. However, once you pass a pointer to a certain datatype to a function that takes a void * you lose all type information. One way to steer your program so it knows which type you passed in is to have a 2nd parameter of type enum which may have values such as INT, FLOAT, DOUBLE etc. etc.

#include <stdio.h>

typedef enum inputTypes
{
    INT,
    DOUBLE,
    CHAR
} inType;

void myfunc(void*, inType);

int main(void)
{
    int    i = 42;
    double d = 3.14;
    char   c = 'a';

    myfunc(&i, INT);
    myfunc(&d, DOUBLE);
    myfunc(&c, CHAR);

    return 0;
}

void myfunc(void* param, inType type)
{  
    switch(type) {
       case INT:
           printf("you passed in int %d\n", *((int *)param));
           break;
       case DOUBLE:
           printf("you passed in double %lf\n", *((double *)param));
           break; 
       case CHAR: 
           printf("you passed in char %c\n", *((char *)param));
           break;
    }
}

Output

you passed in int 42
you passed in double 3.140000
you passed in char a


Yes, it is possible to create a function that accepts multiple type, but that is not how you do it.

In your myfunc, sizeof(param) will always be the same: sizeof is determined at compile time, and will be the size of a pointer.

The reason it works for threads, it generally it is known by the coder what the pointer points to, at compile time, and all you need is a simple cast. If you don't know at compile time what the void * points to, you must pass it at runtime somehow.

The key with void *: You can only cast them back to whatever they were in the first place, and it is up to you to know what that is. A simple void * by itself cannot tell you what it is pointing to.


sizeof(param) will always return the size of a pointer, so presumably 8 if you are on a 64-bit system. This has nothing to do with what it's pointing to.


Doesn't work because sizeof(param) is trying to take the size of a pointer.


The size of a void* is completely dependent on the system and determined at compile time, not on what is actually contained within it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜