Search code examples
cpointersstructcastingvoid

void * cast for generic function


I'm trying to build a generic function as the one below

struct x {
    int l;
    char p;
};

struct y {
    int l;
    char p;
};

void test (void *t, int type)
{
   if (type)
     (struct y*)t;
   else
     (struct x*)t;

   t->l = 6;
   t->p = 'k';
}

Something like this, the variable t must have the same name for cast x* or y*. Do you have any idea if this is possible or have other suggestions? Thank you!


Solution

  • This:

    (struct y*)t;
    

    Doesn't permanently change the type of t. It takes the value of t, converts the type of that value from void * to struct y *, then discards that value since nothing is done with it.

    After converting the pointer value, you can then dereference the resulting expression and assign to the appropriate member.

    if (type)
      ((struct y*)t)->l = 1;
    else
      ((struct x*)t)->l = 1;
    

    Alternately, you can assign the value of t to a variable of the appropriate type and use that going forward:

    if (type) {
        struct y *y1 = t;
        y1->l = 1;
        // do more with y1
    } else {
        struct x *x1 = t;
        x1->l = 1;
        // do more with x1
    }
    

    If what you want is to work on two structs that have some common members, you need to create a separate struct with the common members and include that in each of the two structs.

    struct z {
        int l;
        char p;
    };
    
    struct x {
        struct z z;
        int i;
    };
    
    struct y {
        struct z z;
        double j;
    };
    
    void test(struct z *t)
    {
       t->l = 6;
       t->p = 'k';
    }
    
    int main()
    {
        struct x x1;
        struct y y1;
        test((struct z*)&x1);
        test((struct z*)&y1);
    }
    

    The above cast is allowed because a pointer to a struct can be safely converted to a pointer to its first member.