_ptr and _srcptr types

Emmanuel Thomé Emmanuel.Thome at inria.fr
Fri Jan 18 13:29:00 UTC 2019


Hi,

Does that change go to the gmp repo (and maybe to some release someday)
or not ?

Cheers,

E.

On Tue, Jun 05, 2018 at 09:36:40PM +0200, Emmanuel Thomé wrote:
> Hi,
> 
> Just wondering... where do we go from here ?
> 
> E.
> 
> On Sat, May 26, 2018 at 09:38:17PM +0200, Emmanuel Thomé wrote:
> > On Sat, May 26, 2018 at 09:54:37AM +0200, Niels Möller wrote:
> > > I think I'd like to add something like
> > > 
> > >   When an array is used as a function argument in C, it is not passed by
> > >   value, instead its value is a pointer to the first element. In C
> > >   jargon, this is sometimes referred to as the array "decaying" to a
> > >   pointer. For GMP types like mpz_t, that means that the function called
> > >   gets a pointer to the caller's mpz_t value, which is why no explicit &
> > >   operator is needed when passing output arguments. [this is related to
> > >   the section Parameter Conventions]
> > >   
> > >   GMP defines names for these pointer types, e.g., mpz_ptr corresponding
> > >   to mpz_t, and mpz_srcptr corresponding to const mpz_t. Most functions
> > >   don't need to use these pointer types directly; it works fine to
> > >   declare a function using the mpz_t or const mpz_t as the argument
> > >   types, the same "pointer decay" happens in the background regardless.
> > > 
> > >   Occasionally, it is useful to manipulate pointers directly, e.g, to
> > >   conditionally swap *references* to a function's inputs without
> > >   changing the *values* as seen by the caller, or returning a pointer to
> > >   an mpz_t which is part of a larger structure. For these cases, the
> > >   pointer types are necessary. And a mpz_ptr can be passed as argument
> > >   to any GMP function declared to take an mpz_t argument.
> > 
> > I wondered indeed whether such an explanation is needed. One may consider
> > that it's not the purpose of the Fine Manual to teach the user about C. I
> > like your suggested text, though. (typo: "a mpz_ptr" -> "an mpz_ptr").
> > 
> > > > +equivalent to the following code, which is given for illustratory
> > > > +purposes only:
> > > > +
> > > > + at example
> > > > +    typedef some_internal_data_type mpz_t[1];
> > > > +    typedef some_internal_data_type * mpz_ptr;
> > > > +    typedef const some_internal_data_type * mpz_srcptr;
> > > > + at end example
> > > 
> > > I think it's confusing with a made-up name for the internal types, but
> > > actual names for types defined. I'd prefer to either use the actual
> > > internal name __mpz_struct instead of some_internal_data_type above, or
> > > change to the obviously made up name foo consistently, like
> > > 
> > >     typedef foo_internal foo_t[1];
> > >     typedef foo_internal * foo_ptr;
> > >     typedef const foo_internal * foo_srcptr;
> > 
> > Yes, it's much better (and I have a strong preference for the latter).
> > 
> > E.
> > _______________________________________________
> > gmp-devel mailing list
> > gmp-devel at gmplib.org
> > https://gmplib.org/mailman/listinfo/gmp-devel
> _______________________________________________
> gmp-devel mailing list
> gmp-devel at gmplib.org
> https://gmplib.org/mailman/listinfo/gmp-devel
-------------- next part --------------
diff -r 036ddbf61ac6 doc/gmp.texi
--- a/doc/gmp.texi	Sat Jan 05 15:43:42 2019 +0100
+++ b/doc/gmp.texi	Fri Jan 18 14:28:24 2019 +0100
@@ -1982,6 +1982,62 @@
 Also, in general @code{mp_bitcnt_t} is used for bit counts and ranges, and
 @code{size_t} is used for byte or character counts.
 
+ at sp 1
+
+ at cindex Pointer types
+ at tindex @code{mpz_ptr}
+ at tindex @code{mpz_srcptr}
+ at tindex @code{mpq_ptr}
+ at tindex @code{mpq_srcptr}
+ at tindex @code{mpf_ptr}
+ at tindex @code{mpf_srcptr}
+ at tindex @code{gmp_randstate_ptr}
+ at tindex @code{gmp_randstate_srcptr}
+Internally, GMP data types such as @code{mpz_t} are defined as
+one-element arrays, whose element type is part of the GMP
+internals (@pxref{Internals}).
+
+When an array is used as a function argument in C, it is not passed by
+value, instead its value is a pointer to the first element. In C
+jargon, this is sometimes referred to as the array "decaying" to a
+pointer. For GMP types like mpz_t, that means that the function called
+gets a pointer to the caller's mpz_t value, which is why no explicit &
+operator is needed when passing output arguments. [this is related to
+the section Parameter Conventions]
+
+GMP defines names for these pointer types, e.g., mpz_ptr corresponding
+to mpz_t, and mpz_srcptr corresponding to const mpz_t. Most functions
+don't need to use these pointer types directly; it works fine to
+declare a function using the mpz_t or const mpz_t as the argument
+types, the same "pointer decay" happens in the background regardless.
+
+Occasionally, it is useful to manipulate pointers directly, e.g, to
+conditionally swap *references* to a function's inputs without
+changing the *values* as seen by the caller, or returning a pointer to
+an mpz_t which is part of a larger structure. For these cases, the
+pointer types are necessary. And a mpz_ptr can be passed as argument
+to any GMP function declared to take an mpz_t argument.
+
+Their definition is equivalent to the following code, which is given
+for illustratory purposes only:
+
+ at example
+    typedef foo_internal foo_t[1];
+    typedef foo_internal * foo_ptr;
+    typedef const foo_internal * foo_srcptr;
+ at end example
+
+The following pointer types are defined by GMP:
+ at itemize
+ at item @code{mpz_ptr} for pointers to the element type in @code{mpz_t}
+ at item @code{mpz_srcptr} for @code{const} pointers to the element type in @code{mpz_t}
+ at item @code{mpq_ptr} for pointers to the element type in @code{mpq_t}
+ at item @code{mpq_srcptr} for @code{const} pointers to the element type in @code{mpq_t}
+ at item @code{mpf_ptr} for pointers to the element type in @code{mpf_t}
+ at item @code{mpf_srcptr} for @code{const} pointers to the element type in @code{mpf_t}
+ at item @code{gmp_randstate_ptr} for pointers to the element type in @code{gmp_randstate_t}
+ at item @code{gmp_randstate_srcptr} for @code{const} pointers to the element type in @code{gmp_randstate_t}
+ at end itemize
 
 @node Function Classes, Variable Conventions, Nomenclature and Types, GMP Basics
 @section Function Classes
@@ -2071,7 +2127,9 @@
 
 GMP types like @code{mpz_t} are implemented as one-element arrays of certain
 structures.  Declaring a variable creates an object with the fields GMP needs,
-but variables are normally manipulated by using the pointer to the object.  For
+but variables are normally manipulated by using the pointer to the
+object.  The appropriate pointer types (@ref{Nomenclature and Types}) may
+be used to explicitly manipulate the pointer.  For
 both behavior and efficiency reasons, it is discouraged to make copies of the
 GMP object itself (either directly or via aggregate objects containing such GMP
 objects).  If copies are done, all of them must be used read-only; using a copy
@@ -2129,6 +2187,13 @@
 
 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 @code{foo}
+could be:
+
+ at example
+void foo (mpz_ptr result, mpz_srcptr param, unsigned long n);
+ at end example
+
 
 
 @need 1000
@@ -4501,10 +4566,13 @@
 (@pxref{Rational Number Functions}) then @code{mpq_canonicalize} must be
 called before any other @code{mpq} functions are applied to that @code{mpq_t}.
 
- at deftypefn Macro mpz_t mpq_numref (const mpq_t @var{op})
- at deftypefnx Macro mpz_t mpq_denref (const mpq_t @var{op})
+ at deftypefn Macro mpz_ptr mpq_numref (const mpq_t @var{op})
+ at deftypefnx Macro mpz_ptr mpq_denref (const mpq_t @var{op})
 Return a reference to the numerator and denominator of @var{op}, respectively.
-The @code{mpz} functions can be used on the result of these macros.
+The @code{mpz} functions can be used on the result of these macros.  Such
+calls may modify the numerator or denominator. However, care
+should be taken so that @var{op} remains in canonical form prior to a
+possible later call to an @code{mpq} function.
 @end deftypefn
 
 @deftypefun void mpq_get_num (mpz_t @var{numerator}, const mpq_t @var{rational})
diff -r 036ddbf61ac6 gmp-h.in
--- a/gmp-h.in	Sat Jan 05 15:43:42 2019 +0100
+++ b/gmp-h.in	Fri Jan 18 14:28:24 2019 +0100
@@ -220,13 +220,14 @@
 typedef __gmp_randstate_struct gmp_randstate_t[1];
 
 /* Types for function declarations in gmp files.  */
-/* ??? Should not pollute user name space with these ??? */
 typedef const __mpz_struct *mpz_srcptr;
 typedef __mpz_struct *mpz_ptr;
 typedef const __mpf_struct *mpf_srcptr;
 typedef __mpf_struct *mpf_ptr;
 typedef const __mpq_struct *mpq_srcptr;
 typedef __mpq_struct *mpq_ptr;
+typedef const __gmp_randstate_struct *gmp_randstate_srcptr;
+typedef __gmp_randstate_struct *gmp_randstate_ptr;
 
 
 #if __GMP_LIBGMP_DLL


More information about the gmp-devel mailing list