I see two parts of your question. The first part of how typedef works to pass arguments to functions is best illustrated with an example. Without this, I have to guess a little.
In C function declarations , an array parameter is equivalent to a pointer . That's why you see (for example) an equivalent core function,
int main(int argc, char **argv)
and
int main(int argc, char *argv[])
Similarly, if a function in your program is declared
int func(__mpz_struct *arg)
he would be equivalent
int func(__mpz_struct arg[])
and therefore to
int func(mpz_t arg)
In addition, on the call side, if you have a variable of type mpz_t, therefore an array, and you pass it to a function, " pointer evasion " takes effect: in an expression, if you use an (name) array, it "splits" into a pointer on your first item. This way you can call the function:
mpz_t value; func(value);
Of course, in order to modify these mpz_t objects outside of the API functions, you still need to know about their true nature.
The side effects that you are talking about, I would also have to guess about them. Perhaps this means that you should know that you are working with pointers inside functions. We can assume that it is better to make this explicit using pointer syntax.