documentation on internals not up to date
Niels Möller
nisse at lysator.liu.se
Fri Apr 27 08:50:36 UTC 2018
"Marco Bodrato" <bodrato at mail.dm.unipi.it> writes:
> from gmp-bugs.
>
> Il Ven, 27 Aprile 2018 7:21 am, Niels Möller ha scritto:
>> "Marco Bodrato" <bodrato at mail.dm.unipi.it> writes:
>
>>> Currently there's always at least one readable limb, so for instance
>>> @code{mpz_get_ui} can fetch @code{_mp_d[0]} unconditionally (though its
>>> value is then only wanted if @code{_mp_size} is non-zero).
>>
>> Maybe change "is only wanted if" to "is valid only if" or "is usable
>> only if". At some point, I suffered the misunderstanding that _mp_size
>> == 0 implies _mp_d[0] == 0, which isn't right.
>
> Do you mean that we should underline that also with _mp_size == 0, any
> limb above the size of the number is undefined?
This is a minor point, but.... The thing is, that when we say that
_mp_d[0] is readable but "not wanted", that leaves it somewhat unclear
what the value might be, maybe it's always a redundant zero? I think we
should be more explicit, making it clear from the docs that when we read
_mp_d[0] and _mp_size == 0, the value read must be considered garbage
and not used in any way.
>> _mp_alloc == 0 and _mp_size != 0 is a read-only value, _mp_d is neither
>> written, reallocated or freed by mpz functions. It must not be passed as
>> destination argument to any mpz function. Should also link to docs for
>> mpz_roinit_n and MPZ_ROINIT_N.
>
> Currently, if an mpz_t is initialised with _roinit, it can be passed to
> _clear or _clears with no errors. Should we document this? I think we
> should.
>
> Moreover, the various mpz_set_ functions should work smoothly too.
I'd prefer that we not document any way to pass _roinit values to any
mpz functions taking a non-const mpz_t, even if it happens to work in
the current implementation. Maybe as a later extension, *if* we find
some use cases where it provides a significant advantage.
I'd also consider backing that up by having the realloc function abort
in case _mp_alloc == 0 but _mp_size != 0.
> And I'm
> quite sure that any mpz function is able to "overwrite" an mpz_t that was
> initialised with _roinit. I mean, the following code actually works:
>
> int main(void)
> {
> mpz_t f0, f1, fn;
> int n = 10;
> mp_limb_t dummy = 1;
>
> mpz_roinit_n (f0, &dummy, 1);
> mpz_roinit_n (f1, &dummy, 1);
> mpz_roinit_n (fn, &dummy, 0);
>
> for(;--n;) {
> mpz_add (fn, f0, f1);
> mpz_swap (f0, f1);
> mpz_swap (f1, fn);
> }
> gmp_printf ("%Zd\n", f1);
> mpz_clears (f0, f1, fn, NULL);
> }
Even if it works, I don't think we should document or encourage such
use. I'd recommend this way to add two roinit values is
mpz_t f0, f1, fn;
mpz_init(fn);
mpz_add (fn, mpz_roinit_n (f0, ...), mpz_roinit_n (f1, ...));
And switching arguments above, say
mpz_add (mpz_roinit_n (f0, ...), fn, mpz_roinit_n (f1, ...));
would give a compile time warning because the roinit return value is
const. Which is a good think, imo.
Regards,
/Niels
--
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.
More information about the gmp-devel
mailing list