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?).