Parameter Conventions
=====================
When a GMP variable is used as a function parameter, it's
effectively a call-by-reference, meaning if the function stores a value
there it will change the original in the caller.
When a function is going to return a GMP result, it should designate
a parameter that it sets, like the library functions do. More than one
value can be returned by having more than one output parameter, again
like the library functions. A `return' of an `mpz_t' etc doesn't
return the object, only a pointer, and this is almost certainly not
what's wanted.
Here's an example accepting an `mpz_t' parameter, doing a
calculation, and storing the result to the indicated parameter.
void
foo (mpz_t result, mpz_t param, unsigned long n)
{
unsigned long i;
mpz_mul_ui (result, param, n);
for (i = 1; i < n; i++)
mpz_add_ui (result, result, i*7);
}
int
main (void)
{
mpz_t r, n;
mpz_init (r);
mpz_init_set_str (n, "123456", 0);
foo (r, n, 20L);
gmp_printf ("%Zd\n", r);
return 0;
}
`foo' works even if the mainline passes the same variable as both
`param' and `result', just like the library functions. But sometimes
this is tricky to arrange, and an application might not want to bother
supporting that sort of thing.
For interest, the GMP types `mpz_t' etc are implemented as
one-element arrays of certain structures. This is why declaring a
variable creates an object with the fields GMP needs, but then using it
as a parameter passes a pointer to the object. Note that the actual
fields in each `mpz_t' etc are for internal use only and should not be
accessed directly by code that expects to be compatible with future GMP
releases.