简体   繁体   中英

typedef array vs. typedef pointer

GMP declares the following structure:

typedef struct
{
  int _mp_alloc;
  int _mp_size;
  mp_limb_t *_mp_d;
} __mpz_struct;

and then these two type definitions:

typedef __mpz_struct mpz_t[1];
typedef __mpz_struct *mpz_ptr;

What is the reasoning behind those two separate (and seemingly same) definitions? What is the difference between them?

Although arrays and pointers are syntactically very similar, they are not the same.

The first typedef in your example allows declaration of an object of type mpz_t , which will be a single _mpz_struct object (an array of size 1 ); however, because it is declared as an array, its name can be used as a pointer (for example, when passing to a function that requires a pointer to that structure type).

The second typedef is a simple pointer. Any variable thus declared will need to have the address of an actual structure assigned to it before it can be used (dereferenced).

The latter type will allow changes to the particular object it points to, whereas the former type is a 'fixed' pointer to the particular object (or 'fake' array) declared.

I don't have access to the GMP library, so I can't make an example using that, but the following code may illustrate the subtle difference between the two types:

#include <stdio.h>

typedef struct {
    int a;
    int b;
    double d;
} MyStruct;

typedef MyStruct MS_t[1];
typedef MyStruct* MS_ptr;

int main()
{
    MS_t mt;
    MS_ptr mp;
    printf("Size of type = %zu; Size of pointer = %zu\n\n", sizeof(MS_t), sizeof(MS_ptr));

    mt->a = 1; mt->b = 2; mt->d = 3.141; // Good - "mt" can be used as a pointer to first (only) element of the array.
//  mp->a = 3; mp->b = 7; mp->d = 3.141; // UNDEFINED BEHAVIOUR - mp doesn't point to anything.

    MyStruct ms1, ms2 = { 3, 8, 42.42 };
    mp = &ms1;
    mp->a = 2; mp->b = 4; mp->d = 2.718; // OK - mp now points to a valid structure (ms1)

    printf("MT: %d %d %f\n", mt->a, mt->b, mt->d);
    printf("MP: %d %d %f\n", mp->a, mp->b, mp->d);

    // Let's try to change addresses:
    mp = &ms2; // We can change what "mp" points to whenever we like
    printf("MP: %d %d %f\n", mp->a, mp->b, mp->d); // Different address -> different structure -> different data!
//  mt = &ms2; // ERROR: array type 'MS_t' (aka 'MyStruct [1]') is not assignable

    mp = mt; // We can even use "mt" as an address to assign to "mp"
    printf("MP: %d %d %f\n", mp->a, mp->b, mp->d); // This shows the 'first' data set values

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM