1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Passing various types to a function?

Discussion in 'C' started by bytes_and_bits, Jun 17, 2010.

  1. bytes_and_bits

    bytes_and_bits New Member

    Joined:
    Jun 17, 2010
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Hello,

    I have several pointers to structures types which I would like to pass to a function. However, once in the function, I need to know the correct pointer to struct type in order to continue the function's code. Please consider the following code:


    Code:
    #include <stdio.h>typedef struct tag1{int a;long h;}t1;typedef struct tag2{int a;int *y;}t2;void f1(void *i){ t1 *R = (t1*)i; R->a = 9;}int main(){ t1 x; t2 y; f1(&x);}
    Therefore if I call f1 with this line:

    f1(&x);

    everything is okay. But if I call f1 with this line:

    f1(&y);

    Then I have a problem where the member "a" in t2 doesn't get 9 assigned to it.

    What can be done so that which ever type of pointer to struct I decide to pass into the f1 function can be automatically typecasted to the correct pointer to struct type?

    In reference to code below is an alternative. Therefore, if s = 1, I will do something... with... t1, then another time if s = 2, I will do something else ...with t2. So like this:


    Code:
    #include <stdio.h>typedef struct tag1{int a;long h;}t1;typedef struct tag2{int a;int *y;}t2;void f1(void *i, int s, int r){ if(s == 1) { t1 *X = (t1*)i; X->a = r; } else if(s==2) { t2 *Y = (t2*)i; Y->a = r; }}int main(){t1 x;t2 y;f1(&x,1,10);f1(&y,2,33);}

    In my real project, this so called "something" that we do for t1 is also done identically for t2 and can be 30 or 40 lines long! Also, to remind ourselves that s can be 1 to perhaps 50 or 100.... types therefore, f1() will be very long with alot of
    "if's/else if" statements containing the the same 50 or 100 lines. I am not too crazy about this. Ther's got to be a better way.

    I would like to have the common code (code such as the X->a = r;)
    above written once in my function while being able to cast the first argument to the appropriate type.

    I have heard of function-style macro that can resolve this but I wouldn't know exactly how to do this.

    All help and suggestions are welcome and appreciated! Thanks
     
  2. bytes_and_bits

    bytes_and_bits New Member

    Joined:
    Jun 17, 2010
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Hello, Please excuse my innitial post... here it is again with proper coding emplacement:

    I have several pointers to structures types which I would like to pass to a function. However, once in the function, I need to know the correct pointer to struct type in order to continue the function's code. Please consider the following code:

    Code:
    #include <stdio.h>
    
    typedef struct tag1{
    int a;
    long h;
    }t1;
    
    typedef struct tag2{
    int a;
    int *y;
    }t2;
    
    void f1(void *i)
    {
       t1 *R = (t1*)i;	
       R->a = 9;
    }
    
    int main()
    {
       t1 x;
       t2 y;
       f1(&x);
    }
    
    Therefore if I call f1 with this line:

    f1(&x);

    everything is okay. But if I call f1 with this line:

    f1(&y);

    Then I have a problem where the member "a" in t2 doesn't get 9 assigned to it.

    What can be done so that which ever type of pointer to struct I decide to pass into the f1 function can be automatically typecasted to the correct pointer to struct type?

    In reference to code below is an alternative. Therefore, if s = 1, I will do something... with... t1, then another time if s = 2, I will do something else ...with t2. So like this:


    Code:
    #include <stdio.h>
    
    typedef struct tag1{
    int a;
    long h;
    }t1;
    
    typedef struct tag2{
    int a;
    int *y;
    }t2;
    
    void f1(void *i, int s, int r)
    {
        if(s == 1)
         {
            t1 *X = (t1*)i;	
            X->a = r;
          }
        else if(s==2)
          {
             t2 *Y = (t2*)i;
             Y->a = r;
          }
    }
    
    int main()
    {
    t1 x;
    t2 y;
    
    f1(&x,1, 10);
    f1(&y,2, 40);
    }
    
    In my real project, this so called "something" that we do for t1 is also done identically for t2 and can be 30 or 40 lines long! Also, to remind ourselves that s can be 1 to perhaps 50 or 100.... types therefore, f1() will be very long with alot of
    "if's/else if" statements containing the the same 50 or 100 lines. I am not too crazy about this. Ther's got to be a better way.

    I would like to have the common code (code such as the X->a = r; )
    above written once in my function while being able to cast the first argument to the appropriate type.

    I have heard of function-style macro that can resolve this but I wouldn't know exactly how to do this.

    All help and suggestions are welcome and appreciated! Thanks
     
  3. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    A better solution is to use polymorphism.
    Code:
    class base
    {
    public:
      int a;
    };
    
    class t1 : public class base
    {
    public:
      long h;
    };
    
    class t2 : public class base
    {
    public:
      int *y;
    };
    
    void f(base *B, int n)
    {
      B->a = n;
    }
    
    int main()
    {
      t1 x;
      t2 y;
      f(&x);
      printf("Assigned %d\n",x.a);
    }
    
    I haven't tested this but it should work...

    But to answer your question directly: there is no way. That's why polymorphism is so powerful. With void*'s you had to use massive if/else if ladders all the time in moderately to hugely complex programs where you had a pile of types all with similarities and all needing the same sort of operation done on them.

    There is another way though. You don't need to duplicate the lines, you could just use pointers. You still have the if/else if ladder, but only for initialising the pointers:
    Code:
    void f1(void *i, int s, int r)
    {
        int *a_ptr;
        if(s == 1) a_ptr=&((t1*)i)->a; // not sure I've got the right syntax. Cast i to t1 and ->a
        else if (s==2) a_ptr=&((t2*)i)->a;
    
    // then just those fifty lines once but using the pointer:
    
        *a_ptr = t;
    }
    
    It's not as neat as C++'s polymorphism though, but might be easier to implement.
     

Share This Page