Boost logo

Boost :

Subject: Re: [boost] [core] [noncopyable] Add nonmoveable?
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-04-27 23:38:01


On 27/04/2017 20:53, Andrey Semashev wrote:
> On 04/27/17 02:23, Gavin Lambert wrote:
>> As long as no other symbols are defined in that namespace, what does it
>> matter?
>
> It adds more work to the compiler.

Not really, no. Only free functions can possibly participate in ADL,
and there aren't any in that namespace, so at worst this is a single
lookup into an empty dictionary. I doubt you could even measure it.

>> Yes, and that's better if you're writing a class that (or in a library
>> that) otherwise does not depend on Boost in any way. But if you're
>> taking a dependency on Boost anyway, then boost::noncopyable is less
>> typing than explicitly deleting constructors.
>
> Well, the gain in the number of keystrokes does not outweigh the
> drawbacks, IMO.

I'm still waiting to hear *any* drawbacks. And it's not just the
keystrokes, it's also more self-documenting to see "noncopyable" than to
see deleted copy constructors.

It's also less error-prone -- I've seen quite a few cases in C++98 code
where someone *intended* to declare a private copy constructor to do the
same thing, but they forgot something; typically either forgetting to
declare the copy-assignment operator or forgetting that it needed to be
a reference argument, with the result that it didn't actually do
anything useful. Nothing in C++11 reduces those risks. Using
noncopyable does.

(Another one is renaming the class while forgetting to change the
copy-constructor parameter, making it a regular constructor instead of a
copy-constructor.)

> Because the class is _supposed_ to be non-moveable according to its
> semantics. For example, std::mutex is non-movable not because its
> pthread_mutex_t member is non-movable (it's not) but because mutexes
> should not be movable or copyable as that doesn't make sense and plainly
> dangerous in the intended pattern of use.

Actually, depending on implementation, the pthread_mutex_t might be
non-movable. Futexes, for example, use the address of the mutex as part
of their contract with the kernel, so moving it would break behaviour.

Also, as a non-POD opaque data structure, it's definitely unsafe to
memcpy it, and neither Windows nor Pthreads provide a method to move or
copy one (the closest you can get is to destroy one and create another,
which is typically undefined behaviour if the lock is held or there are
any waiters, or if there might be any concurrent access to it), so even
when not using futexes there is no way to move one safely anyway. So it
is most definitely always non-movable.

> IMO, movability or non-movability is not the reason to convert a class
> to pimpl (pure or not). Very rarely I see a case when an object is not
> movable because of its members (e.g. a mutex) yet it is required to be
> movable by the rest of the program. When that happens it's usually a
> sign of a design problem.

That's not what I was saying. I was saying that if you're making your
class pimpl (or mostly-pimpl) anyway (as is common in some domains for
other reasons), this can automatically specify the copy/move traits of
your class without having to do anything special. (And that you can
consider this when choosing which type of pimpl to use for a given class.)

This is a side-benefit (and falls under Rule of Zero and SRP, as I said
before), but not a motivation in itself.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk