1

Is there a way to do something like this : ?

void set(void* data, void *value, t_flags type)  
{
    if (type & INT)
        *(int*)data = *(int*)value;
    if (type & UINT)
    (...)
}

int i;  
set(&i, 42, INT);

My set function works but I don't know how to call it with number, char '', or string "".

Edit : I've forgot the last argument, but the problem come from the 42 argument.

mantal
  • 1,093
  • 1
  • 20
  • 38
  • 2
    You are passing only two arguments to your function `set`. – haccks Dec 17 '13 at 15:35
  • 2
    Although there is nothing conceptually wrong with your implementation you are just replicating a less powerful `memcpy` - I recommend you use that instead. `#define set (data, value) memcpy(data, value, sizeof(value))` – Sergey L. Dec 17 '13 at 15:38
  • 1
    @thumbmunkeys You should be using `memcpy` directly anyways. Many compilers also offer optimised `memcpy` versions. – Sergey L. Dec 17 '13 at 15:41
  • The type argument is missing when you call set. – Jabberwocky Dec 17 '13 at 15:41

2 Answers2

3

A few things. First, since you're using a void* (which is appropriate) for value, you need to pass a void* as your second argument, instead of a constant. This will work to copy one variable to the next, but there are more efficient ways.

Second, note that for passing a string, you need to pass a pointer to a char pointer, and the char* will get set by the function. (It's up to you whether it's a "soft copy" or "hard copy" - i.e. whether the pointer points to the same place in memory or to another copy of the same string. You said you had set implemented, so I'm guessing you already have it the way you want.

You haven't included your t_flags enum, so I guessed appropriate values.

char  c = 'c';
char* str = "str";
int   i = 42;
char  c2;
char* str2;
char  i2;

set(&c2, &c, CHAR); /* presumably you have a CHAR flag? */
set(&str2, &str, CHARPTR); /* presumably you have a CHARPTR flag? */
set(&i2, &i, INT);

The bigger question for me is why you would want to do this, especially since in your flag you already need to know the type. It's much cleaner (and has much better type checking) to simply do:

c2 = c;
str2 = str;
i2 = i;

I'm assuming this is just for learning about functions, or it's massively simplified for a complex issue. Either way, that's how you do it.

Scott Mermelstein
  • 15,174
  • 4
  • 48
  • 76
  • +1: Excellent point about needing to pass the values from an address, not directly by value. – Jonathan Leffler Dec 17 '13 at 15:51
  • I'm trying to reprotucte the vector from C++ and the only way i found to not write one function per type is void*. I expected C has a trick to do what I want but It's seem i need to use temp variable. – mantal Dec 17 '13 at 16:18
  • 1
    In C++ life is easier, because you have templates. It's possible-but-not-likely that you can do the same using macros. Have you searched for "c vector"? I saw at least two hits pop up that may be of use to you - either to learn from or to use (depending on any licensing restrictions, of course): http://stackoverflow.com/questions/4694401/how-to-replicate-vector-in-c https://gist.github.com/EmilHernvall/953968 (the second does make use of void pointers, but seems a bit more developed than your sample.) – Scott Mermelstein Dec 17 '13 at 16:23
  • Thanks for the links, they solved some other problems I had with vector. – mantal Dec 18 '13 at 09:48
0

Maybe you want this:

void set(void* data, void *value, t_flags type)  
{
    if (type & INT)
        *(int*)data = *(int*)value;
    if (type & UINT)
        *(unsigned int*)data = *(unsigned int*)value;
    if (type & STRING)
        strcpy((char*)data, (char*)value);
    ...
}

int i;  
char string[100] ;
set(&i, 42, 1<<INT);
set(string, "Hello world", 1<<STRING) ;

But it's weird anyway.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115