1

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?

6
  • 1
    typedef __mpz_struct mpz_t[1]; allows GMP to fake out C and with a "pass by reference" Commented Aug 7, 2020 at 13:13
  • @chux-ReinstateMonica Thanks! But then what they do need *mpz_ptr for? Because it is more "correct" and should be used where ever possible? By "correct" I mean the opposite of "fake out". Commented Aug 7, 2020 at 13:16
  • @chux-ReinstateMonica "possible" -> "convenient". Commented Aug 7, 2020 at 13:22
  • In effect you are asking why GMP was designed the way it was. Quite broad. How would you have re-done mpz_add (a, a, b); /* a=a+b */ correctly? In the Darwin selection of competing approaches, typedef __mpz_struct mpz_t[1] won with its "pass by ref". Commented Aug 7, 2020 at 13:26
  • I am not sure why mpz_ptr is typedef __mpz_struct *mpz_ptr; and not typedef mpz_t *mpz_ptr; Commented Aug 7, 2020 at 13:28

1 Answer 1

2

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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! Could you please expand on the "latter type will allow changes to the particular object it points to"? The very first assignment reads mt->a = 3; so it also "changes" the object.
See my edited code. The assignment mt->a = 3 changes the data in the structure but you can never change which structure mt points to. But you can change what mp points to. Does this make things clearer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.