How large are arbitrarily large integers? (Was Re: Bitfield subtlety)

Vincent Lefevre vincent at vinc17.net
Wed Apr 4 10:36:01 UTC 2018


On 2018-03-29 11:27:24 +0200, Niels Möller wrote:
> Richard Biener <rguenther at suse.de> writes:
> 
> > I would be surprised if that wouldn't work everywhere - any reason
> > you have doubts?  To clarify, allocation would work like
> >
> >  void *ptr = malloc (... + sizeof (size_t));
> >  ->_mp_d = (char *)ptr + sizeof (size_t);
> >  size_t *size = ptr;
> 
> That would give bad alignment in the case that limbs are 64 bits but
> size_t only 32 bits (and the x86_64 "x32" abi is something like that,
> right?).

MPFR uses a union:

/* Heap memory handling
   --------------------
   Memory allocated for a significand (mantissa) has the following
   format:
     * A mp_size_t in a mpfr_size_limb_t union (see below).
     * An array of mp_limb_t (not all of them are necessarily used,
       as the precision can change without a reallocation).
   The goal of the mpfr_size_limb_t union is to make sure that
   size and alignment requirements are satisfied if mp_size_t and
   mp_limb_t have different sizes and/or alignment requirements.
   Moreover, pointer conversions are not fully specified by the
   C standard, and the use of a union (and the double casts below)
   might help even if mp_size_t and mp_limb_t have the same size
   and the same alignment requirements. Still, there is currently
   no guarantee that this code is portable. Note that union members
   are not used at all.
*/
typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t;
#define MPFR_GET_ALLOC_SIZE(x) \
  (((mp_size_t *) (mpfr_size_limb_t *) MPFR_MANT(x))[-1] + 0)
#define MPFR_SET_ALLOC_SIZE(x, n) \
  (((mp_size_t *) (mpfr_size_limb_t *) MPFR_MANT(x))[-1] = (n))
#define MPFR_MALLOC_SIZE(s) \
  (sizeof(mpfr_size_limb_t) + MPFR_BYTES_PER_MP_LIMB * (size_t) (s))
#define MPFR_SET_MANT_PTR(x,p) \
  (MPFR_MANT(x) = (mp_limb_t *) ((mpfr_size_limb_t *) (p) + 1))
#define MPFR_GET_REAL_PTR(x) \
  ((mp_limb_t *) ((mpfr_size_limb_t *) MPFR_MANT(x) - 1))

-- 
Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


More information about the gmp-devel mailing list