When a GMP variable is used as a function parameter, it’s effectively a
call-by-reference, meaning that when the function stores a value there it will
change the original in the caller. Parameters which are input-only can be
designated const
to provoke a compiler error or warning on attempting to
modify them.
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, const 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; }
Our function foo
works even if its caller passes the same variable for
param
and result
, just like the library functions. But
sometimes it’s tricky to make that work, and an application might not want to
bother supporting that sort of thing.
Since GMP types are implemented as one-element arrays, using a GMP variable as
a parameter passes a pointer to the object. Hence the call-by-reference.
A more explicit (and equivalent) prototype for our function foo
could be:
void foo (mpz_ptr result, mpz_srcptr param, unsigned long n);