Search code examples
ctypedefgmpruby-c-extension

Possible side effects of doing a typedef of a struct to an array of one element in C


I came across this code.

typedef __mpz_struct MP_INT;
typedef __mpz_struct mpz_t[1];

Here the struct __mpz_struct is a struct that is typedefed to an array of single element. I understand that this is a trick to pass by reference in C. Then mpz_t has been used as a type to declare variables and pass them to function as parameters. Also, There was one more comment

/*
  MP_INT*, MP_RAT* and MP_FLOAT* are used because they don't have side-effects
  of single-element arrays mp*_t
*/

What kind of side effects are they talking about?


Solution

  • Passing an array to a function let's the array decay to a pointer to it's 1st element.

    One can achieve the same effect by applying the Address-Of operator & to a simple variable of the same type as the array's elements.

    Examples:

    struct S
    {
       int i;
       float f;
    };
    

    This

    void set_S(struct S * ps)
    {
      ps->i = 40;
      ps->f = 2.;
    }
    

    is equivalent to

    void set_S(struct S ps[1])
    {
      ps->i = 40;
      ps->f = 2.;
    }
    

    is equivalent to

    void set_S(struct S * ps)
    {
      ps[0].i = 40;
      ps[0].f = 2.;
    }
    

    is equivalent to

    void set_S(struct S ps[1])
    {
      ps[0].i = 40;
      ps[0].f = 2.;
    }
    

    One-Element-Array approach:

    typedef struct S Array_of_S_with_size_1[1];
    
    int main(void)
    {
      Array_of_S_with_size_1 array_of_S_with_size_1;
      array_of_S_with_size_1[0].i = 0;
      array_of_S_with_size_1[0].f = 0.;
    
      set_S(array_of_S_with_size_1);
    
      ...
    }
    

    The above main() provides the same functionality as the following:

    int main(void)
    {
      struct S s;
      s.i = 0;
      s.f = 0.;
    
      set_S(&s);
    
      ...
    }
    

    I do not see any gain using the "One-Element-Array" approach. An expection might be if the &-key is broken on ones keyboard ... ;-)