220 29569 <5af23587-d714-45bd-b04c-77592ba66e03@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Instantiation of default destructor
Date: Mon, 28 Nov 2016 15:24:58 -0800 (PST)
Lines: 265
Approved: news@gmane.org
Message-ID: <5af23587-d714-45bd-b04c-77592ba66e03@isocpp.org>
References: <CAKgx6B+8zzZ131-UZobmUvCgB4YeQ1+wTZadcuT6ieDCofDndg@mail.gmail.com>
 <1a7a1b18-c001-405e-8f7f-09c048c6ee14@isocpp.org>
 <CAKgx6BL_cWfkySo-UpzTdJFHaQHj1Yyho2oyUUN2c2mhq+P0bA@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_7829_270404834.1480375498479"
X-Trace: blaine.gmane.org 1480375503 10608 195.159.176.226 (28 Nov 2016 23:25:03 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 28 Nov 2016 23:25:03 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDLZJYWNDQIMX6PSYECRUBCJ42TPA@isocpp.org Tue Nov 29 00:24:57 2016
Return-path: <std-proposals+bncBDLZJYWNDQIMX6PSYECRUBCJ42TPA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yb0-f200.google.com ([209.85.213.200])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDLZJYWNDQIMX6PSYECRUBCJ42TPA@isocpp.org>)
	id 1cBVI8-0001St-Kd
	for gclcip-std-proposals@m.gmane.org; Tue, 29 Nov 2016 00:24:57 +0100
Original-Received: by mail-yb0-f200.google.com with SMTP id v78sf127155141ybe.0
        for <gclcip-std-proposals@m.gmane.org>; Mon, 28 Nov 2016 15:25:00 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=DCS6J013wP31q9ffBrDHsV1VGvh0iLAF1TJOZePGorM=;
        b=fP8eao9wKieeVQWxlaQz8vSfbBeofALgFsFPNuVHjJwH3V973Ks5ytIHP74ekvWjIy
         wYI6Ac4SMD90JfArdj/RprSrOmqmm2dNWgxeoEtE+CQAkajDHx+ApYe50V75bXXmRZo1
         V8Mvc2JEd9WuKrBol93SdXptST+vkFAfT8TWt4nadMcEbWvOng4xq10iAqmdV9FOepzz
         HVSgZh56yTuF98CrDRnhyP2/j+r27DZSZMjo1pn2j1QIEogXgHM/syKBRsqfDvBhVRWG
         6Bvrskc0rE7qDTwRg943LtRW0i6PmbgB/jsRY1eC6J2tTkfV3kfXl6LAzWZiyrfkftpl
         2wiw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=DCS6J013wP31q9ffBrDHsV1VGvh0iLAF1TJOZePGorM=;
        b=eX0mGABlvvoSXjuUudqF25a/BtDT34lLm9RVzzb1PbcUQAy/HLMLU9JT8zeUpODsAw
         85Krf1z/lSVq3IJ9qlTV+CBALL3qG9hwlNCY8Hi441CEWTKPTtLWVDyjtoIgm7MAYa2E
         f5QDnxf0GL9r/RRlrugZiIztB7qtdA1x8Uaji9QCdkg8Z9oPUH/GldsfHZss0ng4v2vi
         miwh0pMSbHYC8mcNCkOp+z2Yjb0RnP9DbtycfhlqhSrqBOoh6w9vJD/QklInOfixIgwm
         cfD+9O5oIr18w5QhYvBjbZJnhrpLAZjdtB8hIKay6aTUUiqt4WxcaD1zUYwczZftyFQW
         K0Ow==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=DCS6J013wP31q9ffBrDHsV1VGvh0iLAF1TJOZePGorM=;
        b=LoZqeg+Q8gJnxto9OC+t9n/S5TiDWXKfILDGnOeKVUzrVRZgvnDAwBeIMrIIcXboHI
         KNIrm5aHZPZFfzpHEi0ssjWDQOaRnfJ0aTF54W749PqOhrgW1UT4zWfEVWAnT44/GxDb
         LxykLoC04l0mjsWh8TiF7ImemTMupvZZkk46DrqQI62zeIM6xGBIhY7JmmvK1jU/EYYy
         ciIpEsUc4RDy2hll4MmM+o/y9M4hGv2VjzA3fp/5Mo14yKTDfmPgPlanO4dagXeQ1pZc
         iZeFi5Mkb9Qg1nMbr6pvzG7jfMGOdOEpTWz+MrDVhQ8kMgYsvSLCzzCoIaQMckbnyhoo
         hJ7g==
X-Gm-Message-State: AKaTC00+AidyBIjHi5M0wRaOp6ymDdq9a9G24PXI63r4XUyEmlY6VF0m5En2LOewyhBjOQ==
X-Received: by 10.129.32.4 with SMTP id g4mr5584420ywg.20.1480375499783;
        Mon, 28 Nov 2016 15:24:59 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.11.242 with SMTP id 105ls11700098oth.30.gmail; Mon, 28 Nov
 2016 15:24:59 -0800 (PST)
X-Received: by 10.157.39.129 with SMTP id c1mr743040otb.15.1480375498959;
        Mon, 28 Nov 2016 15:24:58 -0800 (PST)
In-Reply-To: <CAKgx6BL_cWfkySo-UpzTdJFHaQHj1Yyho2oyUUN2c2mhq+P0bA@mail.gmail.com>
X-Original-Sender: arthur.j.odwyer@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:29569
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/29569>

------=_Part_7829_270404834.1480375498479
Content-Type: multipart/alternative; 
	boundary="----=_Part_7830_1317441430.1480375498479"

------=_Part_7830_1317441430.1480375498479
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Monday, November 28, 2016 at 10:53:00 AM UTC-8, Domen Vrankar wrote:
>
> 2016-11-28 16:11 GMT+01:00 Nicol Bolas <jmck...@gmail.com <javascript:>>:
>
>> On Monday, November 28, 2016 at 7:14:55 AM UTC-5, Domen Vrankar wrote:
>>>
>>>
>>> In this video [1] <https://www.youtube.com/watch?v=3D8AjRD6mU96s> (time=
=20
>>> 57:40) Jason Jurecka was talking about the need to write empty/defaulte=
d=20
>>> destructor in cpp file if you want to declare a class in header file, u=
se=20
>>> it in std::unique_ptr and include its declaration only in cpp file:
>>> [...snip example of PImpl idiom with outer class "A" and impl class=20
>>> "T"...]
>>> For me it's not a big deal to write A::~A() =3D default; in cpp file bu=
t=20
>>> still since we've had that debate I was wondering if it would be feasib=
le=20
>>> to change the wording (don't know how much the standard would have to b=
e=20
>>> changed for that) so that implicit default destructor would be added to=
 the=20
>>> code at the point of first constructor implementation (in the above exa=
mple=20
>>> at the point of A::A(T* ptr_); implementation in .cpp file) and not at =
the=20
>>> end of the file where the class was declared?
>>>
>>
>> You've misunderstood the nature of the problem.=20
>>
>
>> The default destructor will call `unique_ptr::~unique_ptr`. And that=20
>> destructor will call `T::~T()`. The problem is that, unless `T` has been=
=20
>> *defined*, you cannot call its destructor.
>>
>
> I understand that but I always expected that it has to be known at the=20
> point of destructor call like you would declare a variable before using i=
t.
>

You're forgetting that there are two different classes here. Outer class=20
"A" has a constructor and a destructor; impl class "T" also has a=20
constructor and a destructor. The problem is that at the point where you're=
=20
trying to define A's destructor, the nature (e.g. the signature) of T's=20
destructor is not known.
=20
Forget about "where" A's destructor is "defined" in terms of lines of the=
=20
source file. That doesn't matter (or make sense) at all. There is no=20
"defined at the beginning of the file, defined at the end of the file"; or=
=20
at least, not that matters here. All that matters is which scopes can=20
actually see the signature (and existence) of T's destructor, and which=20
ones can't.

The problem will probably get a lot clearer if we avoid talking about=20
constructors and destructors, and just talk about plain old member=20
functions =E2=80=94 since the specialness of these member functions doesn't=
=20
actually affect the core issue at all. The issue is the following:

=3D=3Dalpha.h=3D=3D
template<class T> struct Alpha {
    T *ptr;
};

=3D=3Dbeta.h=3D=3D
#include "alpha.h"
struct Gamma;
struct Beta {
    Alpha<Gamma> a;
    void fbeta() { a.ptr->fgamma(); }
};

=3D=3Dgamma.h=3D=3D
struct Gamma {
    void fgamma();  // defined somewhere else, or whatever; doesn't really=
=20
matter
};

Notice that "beta.h" WILL NOT COMPILE because the compiler has no way of=20
knowing that (*a.ptr) actually has a member function named fgamma =E2=80=94=
 because=20
there is no class definition for struct Gamma in scope. This is NOT FIXABLE=
=20
by moving around function definitions, since the root cause has nothing to=
=20
do with function definitions; it has to do with class definitions. The=20
appropriate fix is either to #include "gamma.h" in "beta.h" (thus pulling a=
=20
class definition into scope), or else move the definition of member=20
function fbeta() from "beta.h" into some other translation unit where=20
"gamma.h" has already been #included.

You can do the following transformations on this example:
- out-of-line a new member function Alpha::falpha() to hold the=20
ptr->fgamma() call
- replace fgamma() with ~Gamma()
- replace fbeta() with ~Beta()
- replace falpha() with ~Alpha()
- replace Gamma with T
- replace Beta with A
- replace Alpha with std::unique_ptr

but none of those transformations change any of the core features of the=20
example.

Sure we *could* introduce a bunch of special cases for when the problem=20
*does* involve constructors and destructors (incidentally, notice that my=
=20
example does not have any analogues for the constructors in your original=
=20
code), but that would just obfuscate the issue and make it harder to teach.=
=20
Look =E2=80=94 I was able to show the core issue to you in a single forum p=
ost,=20
precisely because all the things you brought up turned out to be=20
distractions. Imagine how hard it would be to teach the core issue if all=
=20
those things (constructors, destructors, locations in source files...)=20
*were* to be made significant!  The core issue wouldn't go away; it would=
=20
just get a heck of a lot more confusing to teach anyone.

HTH,
=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5af23587-d714-45bd-b04c-77592ba66e03%40isocpp.or=
g.

------=_Part_7830_1317441430.1480375498479
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, November 28, 2016 at 10:53:00 AM UTC-8, Domen V=
rankar wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
2016-11-28 16:11 GMT+01:00 Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"jav=
ascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"_Eii-mzwBAAJ" rel=3D"n=
ofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onc=
lick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gmail.com</=
a>&gt;</span>:<div><div class=3D"gmail_quote"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex"><div dir=3D"ltr"><span>On Monday, November 28, 2016 at=
 7:14:55 AM UTC-5, Domen Vrankar wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr"><div><div><br></div>In this video <a href=3D=
"https://www.youtube.com/watch?v=3D8AjRD6mU96s" rel=3D"nofollow" target=3D"=
_blank" onmousedown=3D"this.href=3D&#39;https://www.youtube.com/watch?v\x3d=
8AjRD6mU96s&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.yout=
ube.com/watch?v\x3d8AjRD6mU96s&#39;;return true;">[1]</a> (time 57:40) Jaso=
n Jurecka was talking about the need to write empty/defaulted destructor in=
 cpp file if you want to declare a class in header file, use it in std::uni=
que_ptr and include its declaration only in cpp file:<br>[...snip example o=
f PImpl idiom with outer class &quot;A&quot; and impl class &quot;T&quot;..=
..]</div><div>For me it&#39;s not a big deal to write A::~A() =3D default; i=
n cpp file but still since we&#39;ve had that debate I was wondering if it =
would be feasible to change the wording (don&#39;t know how much the standa=
rd would have to be changed for that) so that implicit default destructor w=
ould be added to the code at the point of first constructor implementation =
(in the above example at the point of A::A(T* ptr_); implementation in .cpp=
 file) and not at the end of the file where the class was declared?</div></=
div></blockquote></span><div><br>You&#39;ve misunderstood the nature of the=
 problem. <br></div></div></blockquote><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr"><div><br>The default destructor will call `u=
nique_ptr::~unique_ptr`. And that destructor will call `T::~T()`. The probl=
em is that, unless `T` has been <i>defined</i>, you cannot call its destruc=
tor.<br></div></div></blockquote><div><br></div><div>I understand that but =
I always expected that it has to be known at the point of destructor call l=
ike you would declare a variable before using it.<br></div></div></div></di=
v></blockquote><div><br></div><div>You&#39;re forgetting that there are two=
 different classes here. Outer class &quot;A&quot; has a constructor and a =
destructor; impl class &quot;T&quot; also has a constructor and a destructo=
r. The problem is that at the point where you&#39;re trying to define A&#39=
;s destructor, the nature (e.g. the signature) of T&#39;s destructor is not=
 known.</div><div>=C2=A0</div><div>Forget about &quot;where&quot; A&#39;s d=
estructor is &quot;defined&quot; in terms of lines of the source file. That=
 doesn&#39;t matter (or make sense) at all. There is no &quot;defined at th=
e beginning of the file, defined at the end of the file&quot;; or at least,=
 not that matters here. All that matters is which scopes can actually see t=
he signature (and existence) of T&#39;s destructor, and which ones can&#39;=
t.</div><div><br></div><div>The problem will probably get a lot clearer if =
we avoid talking about constructors and destructors, and just talk about pl=
ain old member functions =E2=80=94 since the specialness of these member fu=
nctions doesn&#39;t actually affect the core issue at all. The issue is the=
 following:</div><div><br></div><div>=3D=3Dalpha.h=3D=3D</div><div>template=
&lt;class T&gt; struct Alpha {</div><div>=C2=A0 =C2=A0 T *ptr;</div><div>};=
<br></div><div><br></div><div>=3D=3Dbeta.h=3D=3D</div><div>#include &quot;a=
lpha.h&quot;</div><div>struct Gamma;</div><div>struct Beta {</div><div>=C2=
=A0 =C2=A0 Alpha&lt;Gamma&gt; a;</div><div>=C2=A0 =C2=A0 void fbeta() { a.p=
tr-&gt;fgamma(); }</div><div>};</div><div><br></div><div>=3D=3Dgamma.h=3D=
=3D</div><div>struct Gamma {<br></div><div>=C2=A0 =C2=A0 void fgamma(); =C2=
=A0// defined somewhere else, or whatever; doesn&#39;t really matter</div><=
div>};</div><div><br></div><div>Notice that &quot;beta.h&quot; WILL NOT COM=
PILE because the compiler has no way of knowing that (*a.ptr) actually has =
a member function named fgamma =E2=80=94 because there is no class definiti=
on for struct Gamma in scope. This is NOT FIXABLE by moving around function=
 definitions, since the root cause has nothing to do with function definiti=
ons; it has to do with class definitions. The appropriate fix is either to =
#include &quot;gamma.h&quot; in &quot;beta.h&quot; (thus pulling a class de=
finition into scope), or else move the definition of member function fbeta(=
) from &quot;beta.h&quot; into some other translation unit where &quot;gamm=
a.h&quot; has already been #included.</div><div><br></div><div>You can do t=
he following transformations on this example:</div><div>- out-of-line a new=
 member function Alpha::falpha() to hold the ptr-&gt;fgamma() call</div><di=
v>- replace fgamma() with ~Gamma()</div><div>- replace fbeta() with ~Beta()=
</div><div>- replace falpha() with ~Alpha()</div><div>- replace Gamma with =
T</div><div>- replace Beta with A</div><div>- replace Alpha with std::uniqu=
e_ptr</div><div><br></div><div>but none of those transformations change any=
 of the core features of the example.</div><div><br></div><div>Sure we *cou=
ld* introduce a bunch of special cases for when the problem *does* involve =
constructors and destructors (incidentally, notice that my example does not=
 have any analogues for the constructors in your original code), but that w=
ould just obfuscate the issue and make it harder to teach. Look =E2=80=94 I=
 was able to show the core issue to you in a single forum post, precisely b=
ecause all the things you brought up turned out to be distractions. Imagine=
 how hard it would be to teach the core issue if all those things (construc=
tors, destructors, locations in source files...) *were* to be made signific=
ant! =C2=A0The core issue wouldn&#39;t go away; it would just get a heck of=
 a lot more confusing to teach anyone.</div><div><br></div><div>HTH,</div><=
div>=E2=80=93Arthur</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5af23587-d714-45bd-b04c-77592ba66e03%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5af23587-d714-45bd-b04c-77592ba66e03=
%40isocpp.org</a>.<br />

------=_Part_7830_1317441430.1480375498479--

------=_Part_7829_270404834.1480375498479--

.
