lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi] Rule of zero [Was: default-member-initializers vs. is_trivial]


From: Greg Chicares
Subject: [lmi] Rule of zero [Was: default-member-initializers vs. is_trivial]
Date: Tue, 20 Apr 2021 13:19:25 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0

On 4/20/21 12:30 PM, Vadim Zeitlin wrote:
[...]
>  Concerning the pursuit of the rule of zero, I have to say that I disagree
> with it and believe that it's always best to write all the ctors
> explicitly, even if just to default them, for all but the most trivial
> classes. I thinks understand why you do what you do, but your approach
> seems to implicitly rely on the infallibility of the programmer writing the

We're mathematicians. Striving for infallibility is our job.

One helpful technique is to minimize the fallibility surface.
E.g., if we never use ::new(), we can never forget to delete()
because the correct number of delete's is zero.

Of course, in times of yore when the only authoritative
reference was the ARM and data segments were 65536 bytes, we
had to use ::new() frequently, so we had to write copy ctors
and copy assignment operators explicitly. These days, we can
use the stack for almost everything, or std::unique_ptr when
we must, but we almost never have to write any of the special
member functions ourselves (unless we're writing low-level
stuff like container classes).

On days when we feel less than fully infallible, we write
assertions. I was hoping that statically asserting that the
four special members for copying and moving are 'trivial'
would guarantee that a class is free of a whole category
of defects. I haven't proven to myself that that won't work,
so I'm still hoping that it might.

> code, as it assumes that if a ctor is not defined, it is because it is not
> needed and not just because it was forgotten. Personally I'd rather avoid
> assuming this and explicitly show that it wasn't forgotten, but was
> intentionally omitted by writing the default version

The default ctor is a unique kind of special member function,
for which memcpy-ability is not the definition of triviality.

But if I write an explicit ctor and no default ctor, and the
code compiles, I don't see why I should fret over whether it
was deliberately omitted or just forgotten. If I need it, but
don't have it, the compiler will tell me; if the compiler
doesn't tell me I need it, then I don't.

> in C++98 I always
> used a stock comment to indicate that it was the case

Exactly:

$ git grep 'Implicitly-declared special member functions do the right thing.' 
|wc -l
48

> but since C++11
> writing "= default" serves the same purpose while being also enforced by
> the compiler, which is much nicer. The gain from omitting these lines just
> doesn't seem to be commensurate with the peace of mind gained from having
> them.

There's value in omitting them: they're clutter; and we've had
cases where a defaulted dtor has to be moved out of a header
so that unique_ptr can find its deleter. And AIUI defaulting
the copy operations prevents the compiler from providing the
move operations for us (at least until they change the Standard
again).

That's why I'm experimenting with a new idea:
 - in almost all classes, never write code that would prevent
   the compiler from generating correct (and non-deleted)
   copy and move functions; and
 - try to find a way to assert this property, so that the
   stock comment above could be replaced by a stock assertion;
 - and then there need be no "=default" clutter.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]