Skip to content

Export of Integer 0 does not output any bytes

CCing @hvr as the author of most of these commits on this stuff.

Motivation

The integer-gmp library has a bit of an inconsistent handling of Integer 0 due to the fact that the underlying base routines don't agree on its handling

  • sizeInBaseWord# - returns a required size of 1 for 0
  • exportWordToMutableByteArray - returns 0 bytes written and doesn't write any bytes of 0

I discovered this issue due to a bug it caused in Edward Kmett's Discrimation library. I can easily see how Edward missed it, as I also only discovered these two functions disagree calling them in ghci, and then reading the C code, as part of debugging what was going on.

Seeing as it seems as if it would be easy to do, I would suggest making these two calls agree on how many bytes 0 takes (either 0 or 1). I now know that the current behvaiour is documented, but, despite having references several of the functions, both Edward and myself appeared to have glossed over that, so I expect others will too.

Proposal

Option 1 - have the size function be honest about not writing any bytes for 0

Change

  if (mp_limb_zero_p(s,sn)) return 1;

to

  if (mp_limb_zero_p(s,sn)) return 0;

in integer_gmp_mpn_sizeinbase in libraries/interger-gmp/cbits/wrappers.c.

Option 2 - have the export function write a 0 byte for 0

Change

  if (mp_limb_zero_p(s,sn)) return 0;

to

  if (mp_limb_zero_p(s,sn)) {
    ((char *)destptr)[destofs] = 0;
    return 1;
  }

in integer_gmp_mpn_export/integer_gmp_mpn_export1 in libraries/interger-gmp/cbits/wrappers.c.

For this last option it is necessary to do it in the wrapper as the GMP upstream documentation indicates that the underlying mpz_export function doesn't write anything on 0 (possibly the origin for this behaviour?).

Edited by twhitehead
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information