GMP and C++11 move constructors

Marco Bodrato bodrato at mail.dm.unipi.it
Sun May 20 21:52:29 UTC 2018


Ciao,

Il Dom, 20 Maggio 2018 2:57 pm, Hans Åberg ha scritto:
>> On 20 May 2018, at 13:37, Marco Bodrato <bodrato at mail.dm.unipi.it>

> It is just curious, because there is a value that guarantees deallocators
> to do nothing, and that is (void*)0.

This is NOT required for a custom deallocator that someone may want to use
with GMP. So that a custom deallocator can avoid to check ;-)

See
https://gmplib.org/manual/Custom-Allocation.html#index-free_005ffunction

> The moved from object, or r-value, then must be in a legal state before
> the destructor is applied. As it is a allocated heap pointer, the simplest

The destructor is applied, but the object may also be reused, right? You
seem to assume that, after move, only the destructor can be called on that
object. I guess this is not what the standard says.

> The only reason is to use mpz_move is to create an API: If GMP changes the
> underlying mpz_t, this code might break.

If the code uses documented features, it will not be broken so easily.

> Now, instead of
>  integer(integer&& x) {mpz_move(value_, x.value_); mpz_init(x.value_);}
> one might try
>  integer(integer&& x) {mpz_move(value_, x.value_); mpz_null(x.value_);}
> using
>  inline void mpz_null(mpz_t x) {
>    x[0]._mp_alloc = 0;
>    x[0]._mp_size = 0;
>    x[0]._mp_d = NULL;    // Setting allocation pointer to null.
>  }

The only real difference I see, for current development code, is that you
can inline the function mpz_null.

> This works in the current implementation, as it just applies 'free', I
> think.
>
> But in the new implementation, it will break, since you use another value
> than NULL.

I do not know what do you mean with "the current" and "the new"...

For sure, if the code uses internals such as _mp_alloc, _mp_size and _mp_d
instead of documented functions, it is exposed, and it may be broken as
soon as the next version is out.

> So, returning to your question above, as the GMP API does not explicitly
> specify that NULL is allowed,

It does even more, the documentation explicitly _forbids_ NULL.

For GMP-6.1.2, see https://gmplib.org/manual/Integer-Internals.html
"there’s always at least one limb allocated, so for instance mpz_set_ui
never needs to reallocate, and mpz_get_ui can fetch _mp_d[0]
unconditionally"

For the current development code,
see https://gmplib.org/repo/gmp/rev/110bcd4c29f4#l2.20
"there's always at least one readable limb, so for instance mpz_get_ui can
fetch _mp_d[0] unconditionally"

In either cases _mp_d[0] must at least be readable, NULL[0] is not.


Ĝis,
m

-- 
http://bodrato.it/papers/



More information about the gmp-discuss mailing list