GMP and C++11 move constructors

Marc Glisse marc.glisse at inria.fr
Mon May 21 10:15:04 UTC 2018


On Mon, 21 May 2018, Hans Åberg wrote:

>> 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 C++ standard says that after the move, the original object is left in a legal, but unspecified state. So it is not usable for anything else but destruction from the point if view of the language. If you change it by std::move it is up to you to make sure nothing bad happens.

This is not the way the standard is usually interpreted. If m is a
moved-from object, it is fine to assign a new value to it with m =
whatever. That's even what std::swap does. It should also be fine to
read from it, although you can't rely on any specific value so that's
not very useful.

>>> 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.
>
> The inline is only because it is in a header, so that the compiler can remove it, causing no overhead.

Inlining mpz_init/mpz_free would provide the same gain, as the compiler
would see that the first sets _mp_alloc to 0 and thus remove the test in
the second one.

>>> But in the new implementation, it will break, since you use another value
>>> than NULL.

If you have a testcase that breaks with the current sources, please post
a MCVE so we know what we are discussing.

-- 
Marc Glisse


More information about the gmp-discuss mailing list