[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Define special member functions inline?
From: |
Greg Chicares |
Subject: |
Re: [lmi] Define special member functions inline? |
Date: |
Sat, 4 Mar 2017 16:23:54 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.6.0 |
On 2017-03-04 02:42, Vadim Zeitlin wrote:
> On Sat, 4 Mar 2017 02:01:07 +0000 Greg Chicares <address@hidden> wrote:
[...big snip...]
> GC> Actually, lmi practice has been to define the dtor and all ctors
> GC> out-of-line whenever any one of them is defined out-of-line. Is there
> GC> any reason to change that convention now?
>
> I don't see any good reason to define the ctors and dtor in the same
> place. My personal rule is to define all defaulted special functions inline
> (because of the above efficiency considerations and also because it avoids
> unnecessary repetition) and also define trivial ctors inline as well
This seems to be the best rule. I'd like lmi to follow this guideline.
But there's one part I don't understand: "also define trivial ctors inline".
Aren't all trivial ctors necessarily either omitted, defaulted or deleted?
C++11 [12/5] says:
| A default constructor is trivial if it is not user-provided and if ...
and [8.4.2/4]:
| A special member function is user-provided if it is user-declared and
| not explicitly defaulted or deleted on its first declaration.
So I think you're saying it's okay to omit declaring special member
functions and let the compiler provide them implicitly, e.g.:
struct S {std::string b;};
or
struct T {operator()();};
but if they're declared and defaulted or deleted then we should write:
class C
{
public:
~C() = default; // good
~C() {}; // do not do this
private:
C(const& C) = delete; // good
C(const& C) {} // do not do this
};
with "=default" or "=delete" always on the declaration, and never
write "=default" or "=delete" out-of-line.
And, as a corollary, if a special member function written out-of-line
has an empty body "{}", then it should be inlined with "=default".
> GC> BTW, if we do change it, then 'wx_new.hpp'...
> GC>
> GC> /// When wx is used as an msw dll, memory is allocated and freed
> GC> /// across dll boundaries, and that causes mpatrol to emit spurious
> GC> /// diagnostics.
> GC> ///
> GC> /// To work around this problem, build these functions as a separate
> GC> /// dll, and use 'new(wx)' to allocate memory that will be freed by
> GC> /// wx--for instance, a frame window that's created in an application
> GC> /// but (unavoidably) freed by a wx dll. The sole purpose of this
> GC> /// workaround is to avoid spurious diagnostics; it is not suggested
> GC> /// that this is a good way to manage memory.
> GC>
> GC> ...and all its baggage might simply be dropped.
>
> Actually, I rather like the idea of using a separate allocator for wx
> objects as it clearly indicates those "new"s that must not be matched by
> "delete"s and allows us to distinguish them from all the others, which,
> ideally, we should get rid of completely because a well-written C++(11)
> program should ideally contain no naked new/delete at all. But it's a
> rather theoretical/ philosophical viewpoint and I'm not sure if it really
> passes cost/benefit analysis, so I'd understand if you decided to get rid
> of all this stuff too.
I find this argument persuasive, so we'll retain new(wx).