Topic: Extending the use of shared_from_this() to


Author: Jakob Riedle <jakob.riedle@gmail.com>
Date: Fri, 2 Dec 2016 07:01:13 -0800 (PST)
Raw View
------=_Part_790_2054613840.1480690873104
Content-Type: multipart/alternative;
 boundary="----=_Part_791_575760040.1480690873104"

------=_Part_791_575760040.1480690873104
Content-Type: text/plain; charset=UTF-8

Hello Folks,

at work it happened to me the second time,
that I needed to construct a shared_ptr/weak_ptr to 'this' within the
constructor.

This
<http://stackoverflow.com/questions/31924396/why-shared-from-this-cant-be-used-in-constructor-from-technical-standpoint>stackoverflow
question made think about the situation from the viewpoint of realizability.

I thus went and implemented my own drop-in replacement for *shared_ptr,
weak_ptr *and *enable_shared_from_this.*
It is linked here:

*Sourceforge: shared_from_this_ctor
<https://sourceforge.net/projects/shared-from-this-ctor/>*

*Outcome:*
Obviously, *enable_shared_from_this **can *allow the user to construct a
shared_ptr
while still in its ctor and simply pass it the *reference_count* object
that enable_shared_from_this holds to
the shared_ptr that the constructed object will be passed to (after
construction). (What a sentence...)

I have tested my apporach and it just works as expected.
This was as far as I'm concerned even acomplished with *no speed or size
overhead*.

*My questions now are:*

   - Has this topic been already discussed somewhere else? What outcome?


   - What do you think? Is such usage still dangerous given a very robust
   implementation with no overhead?


   - Is there any use case for it? At least I had it twice now and it looks
   like, that other people have it as well.

( I know that one could create something using weak_from_raw, but I have
not really dug into it yet. )


*Beyond: Extending the approach to destructors:*
One could argue: "Why not extend it to dtors as well?"

The question is: *Is there any use case for this situation?*
Because the functionality is *perfectly demonstrated in my Library as well*.

It works, as long as all shared_/weak_ptrs that get constructed during the
dtor
get destroyed before dtor is over.
*No duplicate deletion whatsoever - all clean -> it works! (Sadly, allowing
this introduces a little bit of overhead :-) )*



I'd love to hear your thoughts!


Greetings from Munich,
Jakob

--
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 email 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/63b9777b-4657-4047-ba0b-b9815c614bf9%40isocpp.org.

------=_Part_791_575760040.1480690873104
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello Folks,<div><br></div><div>at work it happened to me =
the second time,</div><div>that I needed to construct a shared_ptr/weak_ptr=
 to &#39;t<span style=3D"color: rgb(0, 0, 136); background-color: rgb(250, =
250, 250);">his&#39;=C2=A0</span>within the constructor.</div><div><br></di=
v><div><a href=3D"http://stackoverflow.com/questions/31924396/why-shared-fr=
om-this-cant-be-used-in-constructor-from-technical-standpoint">This </a>sta=
ckoverflow question made think about the situation from the viewpoint of re=
alizability.</div><div><br></div><div>I thus went and implemented my own dr=
op-in replacement for <i>shared_ptr, weak_ptr=C2=A0</i>and <i>enable_shared=
_from_this.</i></div><div>It is linked here:</div><div><i><br></i></div><di=
v><i>Sourceforge:=C2=A0<a href=3D"https://sourceforge.net/projects/shared-f=
rom-this-ctor/">shared_from_this_ctor</a></i></div><div><i><br></i></div><d=
iv><b>Outcome:</b></div><div><div>Obviously,=C2=A0<i>enable_shared_from_thi=
s=C2=A0</i><b>can=C2=A0</b>allow the user to construct a shared_ptr</div><d=
iv>while still in its ctor and simply pass it the=C2=A0<i>reference_count</=
i>=C2=A0object that enable_shared_from_this holds to</div><div>the shared_p=
tr that the constructed object will be passed to (after construction).<font=
 size=3D"1"> (What a sentence...)</font></div><div><br></div><div>I have te=
sted my apporach and it just works as expected.</div><div>This was as far a=
s I&#39;m concerned even acomplished with <b>no speed or size overhead</b>.=
</div></div><div><i><br></i></div><div><b>My questions now are:</b></div><d=
iv><ul><li><font face=3D"georgia, serif">Has this topic been already discus=
sed somewhere else? What outcome?</font></li></ul></div><div><ul><li><font =
face=3D"georgia, serif">What do you think?</font> Is such usage still dange=
rous given a very robust implementation with no overhead?</li></ul></div><d=
iv><ul><li><font face=3D"georgia, serif">Is there any use case for it?</fon=
t> At least I had it twice now and it looks like, that other people have it=
 as well.</li></ul></div><div>( I know that one could create something usin=
g weak_from_raw, but I have not really dug into it yet. )<br></div><div><br=
></div><div><br></div><div><b>Beyond: Extending the approach to destructors=
:</b></div><div>One could argue: &quot;Why not extend it to dtors as well?&=
quot;</div><div><br></div><div>The question is: <b>Is there any use case fo=
r this situation?</b></div><div>Because the functionality is <i>perfectly d=
emonstrated in my Library as well</i>.</div><div><br></div><div>It works, a=
s long as all shared_/weak_ptrs that get constructed during the dtor</div><=
div>get destroyed before dtor is over.</div><div><i>No duplicate deletion w=
hatsoever - all clean -&gt; it works! (Sadly, allowing this introduces a li=
ttle bit of overhead :-) )</i></div><div><i><br></i></div><div><i><br></i><=
/div><div><br></div><div>I&#39;d love to hear your thoughts!</div><div><br>=
</div><div><br></div><div>Greetings from Munich,</div><div>Jakob</div><div>=
<br></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/63b9777b-4657-4047-ba0b-b9815c614bf9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/63b9777b-4657-4047-ba0b-b9815c614bf9=
%40isocpp.org</a>.<br />

------=_Part_791_575760040.1480690873104--

------=_Part_790_2054613840.1480690873104--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 2 Dec 2016 08:47:17 -0800 (PST)
Raw View
------=_Part_842_450149843.1480697237682
Content-Type: multipart/alternative;
 boundary="----=_Part_843_134742408.1480697237683"

------=_Part_843_134742408.1480697237683
Content-Type: text/plain; charset=UTF-8

Your implementation implements this by having `shared_ptr`'s acquiring
constructors check to see if the type inherits from
`enable_shared_from_this`. If it does, then it tries to get a `shared_ptr`
from that. If it can, then it uses that to initialize itself. Otherwise, it
does the usual acquisition stuff, passing itself into
`enable_shared_from_this`'s machinery.

This breaks `make/allocate_shared`'s ability to create the control block
and the `T` object in the same allocation. Your version of these functions
makes no attempt to do so, and there's no way to implement that. If a type
has `enable_shared_from_this`, then it's possible that its constructor
could create a new `shared_ptr` internally, which would allocate the
control block. That's bad, since `make/allocate_shared` want to do that
allocation. That's a big part of the point of these functions.

Personally, I don't like the idea of an object being able to claim
ownership of *itself*, even before it has finished being constructed. That
sounds very wrongly designed.

--
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 email 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/21df2654-d94b-4708-98f4-26d1d7a14e2b%40isocpp.org.

------=_Part_843_134742408.1480697237683
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Your implementation implements this by having `shared_ptr`=
&#39;s acquiring constructors check to see if the type inherits from `enabl=
e_shared_from_this`. If it does, then it tries to get a `shared_ptr` from t=
hat. If it can, then it uses that to initialize itself. Otherwise, it does =
the usual acquisition stuff, passing itself into `enable_shared_from_this`&=
#39;s machinery.<br><br>This breaks `make/allocate_shared`&#39;s ability to=
 create the control block and the `T` object in the same allocation. Your v=
ersion of these functions makes no attempt to do so, and there&#39;s no way=
 to implement that. If a type has `enable_shared_from_this`, then it&#39;s =
possible that its constructor could create a new `shared_ptr` internally, w=
hich would allocate the control block. That&#39;s bad, since `make/allocate=
_shared` want to do that allocation. That&#39;s a big part of the point of =
these functions.<br><br>Personally, I don&#39;t like the idea of an object =
being able to claim ownership of <i>itself</i>, even before it has finished=
 being constructed. That sounds very wrongly designed.<br></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/21df2654-d94b-4708-98f4-26d1d7a14e2b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/21df2654-d94b-4708-98f4-26d1d7a14e2b=
%40isocpp.org</a>.<br />

------=_Part_843_134742408.1480697237683--

------=_Part_842_450149843.1480697237682--

.


Author: Jakob Riedle <jakob.riedle@gmail.com>
Date: Fri, 2 Dec 2016 12:01:15 -0800 (PST)
Raw View
------=_Part_888_169615719.1480708875264
Content-Type: multipart/alternative;
 boundary="----=_Part_889_974774824.1480708875265"

------=_Part_889_974774824.1480708875265
Content-Type: text/plain; charset=UTF-8


>
> This breaks `make/allocate_shared`'s ability to create the control block
> and the `T` object in the same allocation. Your version of these functions
> makes no attempt to do so, and there's no way to implement that.
>

Apparently, this is a non-binding requirement of the standard. I think it
can be relaxed without code breakage, right?
Apart from that, I'm not telling anyone to use my implementation, I'm just
asking, whether people like or dislike the functionality at all.


> Personally, I don't like the idea of an object being able to claim
> ownership of *itself*, even before it has finished being constructed.
> That sounds very wrongly designed.
>

To some extent I can understand your worries.
*You might want to put it this way:*
If you're not owned by any shared_ptr instance (yet), then you are
effectively the owner of yourself.

If an instantiation of a class that derives from enable_shared_from_this is
not put into a shared_ptr later on,
all of it's methods that use shared_from_this() will lead to UB as well.
*This risk of unbound enable_shared_from_this instances, was a trade-off
that has already been accepted by introducing enable_shared_from_this.*

And please note, that in case the shared_ptrs, that have been constructed
in the ctor, all get destroyed, the objects dtor will not be called, since
it still 'owns itself'.


If a type has `enable_shared_from_this`, then it's possible that its
> constructor could create a new `shared_ptr` internally, which would
> allocate the control block.
>

The point of a possible implementation is, that *enable_shared_from_this *obviously
has to allocate the control-block (reference-count-struct) and pass it to
the shared_ptr once assigned.
*But as already state above, the risk of unassigned instances was already
taken*
*and*
*is assumed to not outweight the benefit that comes from allowing usage of
shared_from_this.*


Generally:
Please not just say...

   - it doesn't work. There is (nearly) always a solution, if you are just
   willing to find one.
   - it can be misused. That is always the case, always. The question is,
   whether the risk of misuse outweights the benefit?
   ...and as stated above, if they use *shared_from_this *on instances that
   will never be owned by a shared_ptr, that will be a problem in the
   constructor as well.

Dear Nicol, I'm not your enemy and I don't force you to replace your
opinion with mine.
But I invite you to answer constructively.

--
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 email 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/d18d7caa-a96d-48a1-b290-e8deacc3f0d9%40isocpp.org.

------=_Part_889_974774824.1480708875265
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">This breaks `make/allocate_shared`&#39;s ability to create the control =
block and the `T` object in the same allocation. Your version of these func=
tions makes no attempt to do so, and there&#39;s no way to implement that.<=
br></div></blockquote><div><br></div><div>Apparently, this is a non-binding=
 requirement of the standard. I think it can be relaxed without code breaka=
ge, right?</div><div>Apart from that, I&#39;m not telling anyone to use my =
implementation, I&#39;m just asking, whether people like or dislike the fun=
ctionality at all.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr">Personally, I don&#39;t like the idea of an obj=
ect being able to claim ownership of <i>itself</i>, even before it has fini=
shed being constructed. That sounds very wrongly designed.<br></div></block=
quote><div><br></div><div>To some extent I can understand your worries.</di=
v><div><b>You might want to put it this way:</b></div><div>If you&#39;re no=
t owned by any shared_ptr instance (yet), then you are effectively the owne=
r of yourself.</div><div><br></div><div>If an instantiation of a class that=
 derives from enable_shared_from_this is not put into a shared_ptr later on=
,</div><div>all of it&#39;s methods that use shared_from_this() will lead t=
o UB as well.</div><div><b>This risk of unbound enable_shared_from_this ins=
tances, was a trade-off that has already been accepted by introducing <i>en=
able_shared_from_this</i>.</b></div><div><br></div><div>And please note, th=
at in case the shared_ptrs, that have been constructed in the ctor, all get=
 destroyed, the objects dtor will not be called, since it still &#39;owns i=
tself&#39;.<br></div><div><br></div><div><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(20=
4, 204, 204); padding-left: 1ex;">If a type has `enable_shared_from_this`, =
then it&#39;s possible that its constructor could create a new `shared_ptr`=
 internally, which would allocate the control block.<br></blockquote><div><=
br></div><div>The point of a possible implementation is, that <i>enable_sha=
red_from_this </i>obviously has to allocate the control-block (reference-co=
unt-struct) and pass it to the shared_ptr once assigned.</div><div><i>But a=
s already state above, the risk of unassigned instances was already taken</=
i></div><div><i>and</i></div><div><i>is assumed to not outweight the benefi=
t that comes from allowing usage of shared_from_this.</i></div><div><i><br>=
</i></div><div><br></div><div>Generally:</div><div>Please not just say...</=
div><div><ul><li>it doesn&#39;t work. There is (nearly) always a solution, =
if you are just willing to find one.<br></li><li>it can be misused. That is=
 always the case, always. The question is, whether the risk of misuse outwe=
ights the benefit?<br>...and as stated above, if they use=C2=A0<i>shared_fr=
om_this </i>on instances that will never be owned by a shared_ptr, that wil=
l be a problem in the constructor as well.</li></ul><div>Dear Nicol, I&#39;=
m not your enemy and I don&#39;t force you to replace your opinion with min=
e.</div><div>But I invite you to answer constructively.</div></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/d18d7caa-a96d-48a1-b290-e8deacc3f0d9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d18d7caa-a96d-48a1-b290-e8deacc3f0d9=
%40isocpp.org</a>.<br />

------=_Part_889_974774824.1480708875265--

------=_Part_888_169615719.1480708875264--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 2 Dec 2016 13:07:12 -0800 (PST)
Raw View
------=_Part_885_1142040285.1480712832678
Content-Type: multipart/alternative;
 boundary="----=_Part_886_340640606.1480712832679"

------=_Part_886_340640606.1480712832679
Content-Type: text/plain; charset=UTF-8

On Friday, December 2, 2016 at 3:01:15 PM UTC-5, Jakob Riedle wrote:
>
> This breaks `make/allocate_shared`'s ability to create the control block
>> and the `T` object in the same allocation. Your version of these functions
>> makes no attempt to do so, and there's no way to implement that.
>>
>
> Apparently, this is a non-binding requirement of the standard. I think it
> can be relaxed without code breakage, right?
>

In the sense that code will still *function*, sure.

But what about the sense of code doing what we've told everyone it does?
That implementation note in the standard, where it says that
implementations "should" only perform one allocation, is really important.
Saying that this optimization is the primary reason why `allocate_shared`
exists is not overstating things. Note that while we have `make_unique`, we
don't have `allocate_unqiue`.

We gauge the quality of implementations based on them following that note.
People both expect and *rely upon* this optimization. We do not want to
break optimizations that people have been relying on, even though their
code technically still works. Just as we do not want to make changes to
`basic_string` that make small-string optimizations illegal (we broke COW
strings because that's not an optimization).

Such things would not "break" code in the sense of making it
non-functional, but it would *certainly* get people to stop using the
standard library version.

This sort of thinking has been applied to other things in the standard
library. If our `variant` type required implementers to double-buffer the
internal data, certain people would *never* use it. For them, that's too
much of a tradeoff for the minor benefit of exception safety. And you can
hardly blame them for wanting to avoid it for that reason.

Take this optimization away, and lots of people with stop using the
standard library shared_ptr in favor of either a home-grown shared_ptr or a
home-grown intrusive_ptr. This is to nobody's benefit.

Apart from that, I'm not telling anyone to use my implementation, I'm just
> asking, whether people like or dislike the functionality at all.
>

My point wasn't that your `make_shared` implementation didn't do the right
thing. It's that it *cannot* implement the optimization. And therefore, if
we adopt this, then we are telling people that the optimization no longer
can be used.

This is not a feature which is worth that cost. If you have need of it, you
can use your own `shared_ptr` type that provides this functionality.

Personally, I don't like the idea of an object being able to claim
>> ownership of *itself*, even before it has finished being constructed.
>> That sounds very wrongly designed.
>>
>
> To some extent I can understand your worries.
> *You might want to put it this way:*
> If you're not owned by any shared_ptr instance (yet), then you are
> effectively the owner of yourself.
>

To own something, even with shared ownership, means that you can delete it
(or with shared ownership, terminate your share of that ownership). But you
cannot end the lifetime of an object who's lifetime has not started yet.
And by C++'s rules, an object's lifetime does not begin until one of its
constructors finishes.

Therefore, you cannot claim ownership of an object that is still being
constructed. That would be a logical contradiction of one of these concepts.

So if you're claiming ownership of yourself in your own constructor, then
either you're doing something very wrong, or my idea of the concept of
"ownership" is confused.

If an instantiation of a class that derives from enable_shared_from_this is
> not put into a shared_ptr later on,
> all of it's methods that use shared_from_this() will lead to UB as well.
>

Not anymore; C++17 made a change here. You will get a `bad_weak_ptr`
exception if you call `shared_from_this` on an object which was not bound
to a `shared_ptr`.


> *This risk of unbound enable_shared_from_this instances, was a trade-off
> that has already been accepted by introducing enable_shared_from_this.*
>

My point is not specifically the possibility of misuse. For me, it is the
logic of the situation: what does it mean to have ownership of an object
that does not yet exist?


> If a type has `enable_shared_from_this`, then it's possible that its
>> constructor could create a new `shared_ptr` internally, which would
>> allocate the control block.
>>
>
> The point of a possible implementation is, that *enable_shared_from_this *obviously
> has to allocate the control-block (reference-count-struct) and pass it to
> the shared_ptr once assigned.
>

That doesn't help `make/allocate_shared` to provide the required
optimization. Who allocates it is ultimately *irrelevant*; what matters is
that it gets allocated in the same memory as the type being constructed.
And unless `enable_shared_from_this` actually has the control block within
*itself*, there's no way to prevent the allocation of a separate control
block.

As for what I just mentioned (`enable_shared_from_this` storing the control
block), there was an extensive discussion about this sort of thing in
another thread
<https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/WF0gyN9g2mQ%5B101-125%5D>.
While it may or may not be possible in a theoretical sense, it would
certainly not be possible for `enable_shared_from_this` as it currently
stands to do it. This would require using a new type, due in part to
potentially having to give that type an allocator.


> Generally:
> Please not just say...
>
>    - it doesn't work. There is (nearly) always a solution, if you are
>    just willing to find one.
>    - it can be misused. That is always the case, always. The question is,
>    whether the risk of misuse outweights the benefit?
>    ...and as stated above, if they use *shared_from_this *on instances
>    that will never be owned by a shared_ptr, that will be a problem in the
>    constructor as well.
>
> Dear Nicol, I'm not your enemy and I don't force you to replace your
> opinion with mine.
> But I invite you to answer constructively.
>

What's unconstructive about what I said? I explained the problems I saw in
the proposal: that it doesn't allow `make/allocate_shared` to do their job
correctly, and that it supports a programming construct that I find to be
highly dubious. You may not agree with my arguments or positions, but that
hardly makes them unconstructive.

If you wish to prove point #1 wrong, all you need to do is provide an
implementation where it can actually work. Just make sure that it works
with both `make_shared` *and* `allocate_shared`. Which means you'll need to
keep that allocator around and so forth.

--
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 email 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/53300081-cbc4-43fc-806b-bccb3ef053b3%40isocpp.org.

------=_Part_886_340640606.1480712832679
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, December 2, 2016 at 3:01:15 PM UTC-5, Jakob Rie=
dle wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">This breaks `make/all=
ocate_shared`&#39;s ability to create the control block and the `T` object =
in the same allocation. Your version of these functions makes no attempt to=
 do so, and there&#39;s no way to implement that.<br></div></blockquote><di=
v><br></div><div>Apparently, this is a non-binding requirement of the stand=
ard. I think it can be relaxed without code breakage, right?</div></div></b=
lockquote><div><br>In the sense that code will still <i>function</i>, sure.=
<br><br>But what about the sense of code doing what we&#39;ve told everyone=
 it does? That implementation note in the standard, where it says that impl=
ementations &quot;should&quot; only perform one allocation, is really impor=
tant. Saying that this optimization is the primary reason why `allocate_sha=
red` exists is not overstating things. Note that while we have `make_unique=
`, we don&#39;t have `allocate_unqiue`.<br><br>We gauge the quality of impl=
ementations based on them following that note. People both expect and <i>re=
ly upon</i> this optimization. We do not want to break optimizations that p=
eople have been relying on, even though their code technically still works.=
 Just as we do not want to make changes to `basic_string` that make small-s=
tring optimizations illegal (we broke COW strings because that&#39;s not an=
 optimization).<br><br>Such things would not &quot;break&quot; code in the =
sense of making it non-functional, but it would <i>certainly</i> get people=
 to stop using the standard library version.<br><br>This sort of thinking h=
as been applied to other things in the standard library. If our `variant` t=
ype required implementers to double-buffer the internal data, certain peopl=
e would <i>never</i> use it. For them, that&#39;s too much of a tradeoff fo=
r the minor benefit of exception safety. And you can hardly blame them for =
wanting to avoid it for that reason.<br><br>Take this optimization away, an=
d lots of people with stop using the standard library shared_ptr in favor o=
f either a home-grown shared_ptr or a home-grown intrusive_ptr. This is to =
nobody&#39;s benefit.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>Apart from that, I&#39;m not telling anyone to =
use my implementation, I&#39;m just asking, whether people like or dislike =
the functionality at all.</div></div></blockquote><div><br>My point wasn&#3=
9;t that your `make_shared` implementation didn&#39;t do the right thing. I=
t&#39;s that it <b>cannot</b> implement the optimization. And therefore, if=
 we adopt this, then we are telling people that the optimization no longer =
can be used.<br><br>This is not a feature which is worth that cost. If you =
have need of=20
it, you can use your own `shared_ptr` type that provides this=20
functionality.<br><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Per=
sonally, I don&#39;t like the idea of an object being able to claim ownersh=
ip of <i>itself</i>, even before it has finished being constructed. That so=
unds very wrongly designed.<br></div></blockquote><div><br></div><div>To so=
me extent I can understand your worries.</div><div><b>You might want to put=
 it this way:</b></div><div>If you&#39;re not owned by any shared_ptr insta=
nce (yet), then you are effectively the owner of yourself.</div></div></blo=
ckquote><div><br>To own something, even with shared ownership, means that y=
ou can delete it (or with shared ownership, terminate your share of that ow=
nership). But you cannot end the lifetime of an object who&#39;s lifetime h=
as not started yet. And by C++&#39;s rules, an object&#39;s lifetime does n=
ot begin until one of its constructors finishes.<br><br>Therefore, you cann=
ot claim ownership of an object that is still being constructed. That would=
 be a logical contradiction of one of these concepts.<br><br>So if you&#39;=
re claiming ownership of yourself in your own constructor, then either you&=
#39;re doing something very wrong, or my idea of the concept of &quot;owner=
ship&quot; is confused.<br><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div></div><div>If an instantiation of a class that=
 derives from enable_shared_from_this is not put into a shared_ptr later on=
,</div><div>all of it&#39;s methods that use shared_from_this() will lead t=
o UB as well.</div></div></blockquote><div><br>Not anymore; C++17 made a ch=
ange here. You will get a `bad_weak_ptr` exception if you call `shared_from=
_this` on an object which was not bound to a `shared_ptr`.<br>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><b>This r=
isk of unbound enable_shared_from_this instances, was a trade-off that has =
already been accepted by introducing <i>enable_shared_from_this</i>.</b></d=
iv></div></blockquote><div><br>My point is not specifically the possibility=
 of misuse. For me, it is the logic of the situation: what does it mean to =
have ownership of an object that does not yet exist?<br>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left:1px solid rgb(204,204,204);padding-left:1ex">If a type has `enable_s=
hared_from_this`, then it&#39;s possible that its constructor could create =
a new `shared_ptr` internally, which would allocate the control block.<br><=
/blockquote><div><br></div><div>The point of a possible implementation is, =
that <i>enable_shared_from_this </i>obviously has to allocate the control-b=
lock (reference-count-struct) and pass it to the shared_ptr once assigned.<=
/div></div></blockquote><div><br>That doesn&#39;t help `make/allocate_share=
d` to provide the required optimization. Who allocates it is ultimately <i>=
irrelevant</i>; what matters is that it gets allocated in the same memory a=
s the type being constructed. And unless `enable_shared_from_this` actually=
 has the control block within <i>itself</i>, there&#39;s no way to prevent =
the allocation of a separate control block.<br><br>As for what I just menti=
oned (`enable_shared_from_this` storing the control block), there was an ex=
tensive discussion about this sort <a href=3D"https://groups.google.com/a/i=
socpp.org/forum/#!topic/std-discussion/WF0gyN9g2mQ%5B101-125%5D">of thing i=
n another thread</a>. While it may or may not be possible in a theoretical =
sense, it would certainly not be possible for `enable_shared_from_this` as =
it currently stands to do it. This would require using a new type, due in p=
art to potentially having to give that type an allocator.<br>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div=
>Generally:</div><div>Please not just say...</div><div><ul><li>it doesn&#39=
;t work. There is (nearly) always a solution, if you are just willing to fi=
nd one.<br></li><li>it can be misused. That is always the case, always. The=
 question is, whether the risk of misuse outweights the benefit?<br>...and =
as stated above, if they use=C2=A0<i>shared_from_this </i>on instances that=
 will never be owned by a shared_ptr, that will be a problem in the constru=
ctor as well.</li></ul><div>Dear Nicol, I&#39;m not your enemy and I don&#3=
9;t force you to replace your opinion with mine.</div><div>But I invite you=
 to answer constructively.</div></div></div></blockquote><div><br>What&#39;=
s unconstructive about what I said? I explained the problems I saw in the p=
roposal: that it doesn&#39;t allow `make/allocate_shared` to do their job c=
orrectly, and that it supports a programming construct that I find to be hi=
ghly dubious. You may not agree with my arguments or positions, but that ha=
rdly makes them unconstructive.<br><br>If you wish to prove point #1 wrong,=
 all you need to do is provide an implementation where it can actually work=
.. Just make sure that it works with both `make_shared` <i>and</i> `allocate=
_shared`. Which means you&#39;ll need to keep that allocator around and so =
forth.<br></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/53300081-cbc4-43fc-806b-bccb3ef053b3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/53300081-cbc4-43fc-806b-bccb3ef053b3=
%40isocpp.org</a>.<br />

------=_Part_886_340640606.1480712832679--

------=_Part_885_1142040285.1480712832678--

.


Author: Brittany Friedman <fourthgeek@gmail.com>
Date: Fri, 2 Dec 2016 15:26:02 -0600
Raw View
--001a1138fa2ac855cd0542b395fb
Content-Type: text/plain; charset=UTF-8

There are proposals for an intrusively counted smart ptr:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0468r0.html

I would imagine it much easier to get a retain_ptr to an object in its
constructor when that object is responsible for its own reference count.
This may be a viable alternative to trying to doing this for shared_ptr.

On Fri, Dec 2, 2016 at 3:07 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Friday, December 2, 2016 at 3:01:15 PM UTC-5, Jakob Riedle wrote:
>>
>> This breaks `make/allocate_shared`'s ability to create the control block
>>> and the `T` object in the same allocation. Your version of these functions
>>> makes no attempt to do so, and there's no way to implement that.
>>>
>>
>> Apparently, this is a non-binding requirement of the standard. I think it
>> can be relaxed without code breakage, right?
>>
>
> In the sense that code will still *function*, sure.
>
> But what about the sense of code doing what we've told everyone it does?
> That implementation note in the standard, where it says that
> implementations "should" only perform one allocation, is really important.
> Saying that this optimization is the primary reason why `allocate_shared`
> exists is not overstating things. Note that while we have `make_unique`, we
> don't have `allocate_unqiue`.
>
> We gauge the quality of implementations based on them following that note.
> People both expect and *rely upon* this optimization. We do not want to
> break optimizations that people have been relying on, even though their
> code technically still works. Just as we do not want to make changes to
> `basic_string` that make small-string optimizations illegal (we broke COW
> strings because that's not an optimization).
>
> Such things would not "break" code in the sense of making it
> non-functional, but it would *certainly* get people to stop using the
> standard library version.
>
> This sort of thinking has been applied to other things in the standard
> library. If our `variant` type required implementers to double-buffer the
> internal data, certain people would *never* use it. For them, that's too
> much of a tradeoff for the minor benefit of exception safety. And you can
> hardly blame them for wanting to avoid it for that reason.
>
> Take this optimization away, and lots of people with stop using the
> standard library shared_ptr in favor of either a home-grown shared_ptr or a
> home-grown intrusive_ptr. This is to nobody's benefit.
>
> Apart from that, I'm not telling anyone to use my implementation, I'm just
>> asking, whether people like or dislike the functionality at all.
>>
>
> My point wasn't that your `make_shared` implementation didn't do the right
> thing. It's that it *cannot* implement the optimization. And therefore,
> if we adopt this, then we are telling people that the optimization no
> longer can be used.
>
> This is not a feature which is worth that cost. If you have need of it,
> you can use your own `shared_ptr` type that provides this functionality.
>
> Personally, I don't like the idea of an object being able to claim
>>> ownership of *itself*, even before it has finished being constructed.
>>> That sounds very wrongly designed.
>>>
>>
>> To some extent I can understand your worries.
>> *You might want to put it this way:*
>> If you're not owned by any shared_ptr instance (yet), then you are
>> effectively the owner of yourself.
>>
>
> To own something, even with shared ownership, means that you can delete it
> (or with shared ownership, terminate your share of that ownership). But you
> cannot end the lifetime of an object who's lifetime has not started yet.
> And by C++'s rules, an object's lifetime does not begin until one of its
> constructors finishes.
>
> Therefore, you cannot claim ownership of an object that is still being
> constructed. That would be a logical contradiction of one of these concepts.
>
> So if you're claiming ownership of yourself in your own constructor, then
> either you're doing something very wrong, or my idea of the concept of
> "ownership" is confused.
>
> If an instantiation of a class that derives from enable_shared_from_this
>> is not put into a shared_ptr later on,
>> all of it's methods that use shared_from_this() will lead to UB as well.
>>
>
> Not anymore; C++17 made a change here. You will get a `bad_weak_ptr`
> exception if you call `shared_from_this` on an object which was not bound
> to a `shared_ptr`.
>
>
>> *This risk of unbound enable_shared_from_this instances, was a trade-off
>> that has already been accepted by introducing enable_shared_from_this.*
>>
>
> My point is not specifically the possibility of misuse. For me, it is the
> logic of the situation: what does it mean to have ownership of an object
> that does not yet exist?
>
>
>> If a type has `enable_shared_from_this`, then it's possible that its
>>> constructor could create a new `shared_ptr` internally, which would
>>> allocate the control block.
>>>
>>
>> The point of a possible implementation is, that *enable_shared_from_this
>> *obviously has to allocate the control-block (reference-count-struct)
>> and pass it to the shared_ptr once assigned.
>>
>
> That doesn't help `make/allocate_shared` to provide the required
> optimization. Who allocates it is ultimately *irrelevant*; what matters
> is that it gets allocated in the same memory as the type being constructed.
> And unless `enable_shared_from_this` actually has the control block within
> *itself*, there's no way to prevent the allocation of a separate control
> block.
>
> As for what I just mentioned (`enable_shared_from_this` storing the
> control block), there was an extensive discussion about this sort of
> thing in another thread
> <https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/WF0gyN9g2mQ%5B101-125%5D>.
> While it may or may not be possible in a theoretical sense, it would
> certainly not be possible for `enable_shared_from_this` as it currently
> stands to do it. This would require using a new type, due in part to
> potentially having to give that type an allocator.
>
>
>> Generally:
>> Please not just say...
>>
>>    - it doesn't work. There is (nearly) always a solution, if you are
>>    just willing to find one.
>>    - it can be misused. That is always the case, always. The question
>>    is, whether the risk of misuse outweights the benefit?
>>    ...and as stated above, if they use *shared_from_this *on instances
>>    that will never be owned by a shared_ptr, that will be a problem in the
>>    constructor as well.
>>
>> Dear Nicol, I'm not your enemy and I don't force you to replace your
>> opinion with mine.
>> But I invite you to answer constructively.
>>
>
> What's unconstructive about what I said? I explained the problems I saw in
> the proposal: that it doesn't allow `make/allocate_shared` to do their job
> correctly, and that it supports a programming construct that I find to be
> highly dubious. You may not agree with my arguments or positions, but that
> hardly makes them unconstructive.
>
> If you wish to prove point #1 wrong, all you need to do is provide an
> implementation where it can actually work. Just make sure that it works
> with both `make_shared` *and* `allocate_shared`. Which means you'll need
> to keep that allocator around and so forth.
>
> --
> 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
> email 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/53300081-cbc4-43fc-
> 806b-bccb3ef053b3%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/53300081-cbc4-43fc-806b-bccb3ef053b3%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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 email 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/CADbh%2BeQFk1dMMDW-02TFn4JUgc0-Cja%2Bfh7rZ7aLGm8y1UZdzg%40mail.gmail.com.

--001a1138fa2ac855cd0542b395fb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">There are proposals for an intrusively counted smart ptr:<=
div><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p046=
8r0.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0468r0.h=
tml</a><br></div><div><br></div><div>I would imagine it much easier to get =
a retain_ptr to an object in its constructor when that object is responsibl=
e for its own reference count. This may be a viable alternative to trying t=
o doing this for shared_ptr.</div></div><div class=3D"gmail_extra"><br><div=
 class=3D"gmail_quote">On Fri, Dec 2, 2016 at 3:07 PM, Nicol Bolas <span di=
r=3D"ltr">&lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmck=
esson@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><span class=3D"">On Friday, December 2, 2016 at 3:01:15 PM UT=
C-5, Jakob Riedle wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D=
"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">This breaks =
`make/allocate_shared`&#39;s ability to create the control block and the `T=
` object in the same allocation. Your version of these functions makes no a=
ttempt to do so, and there&#39;s no way to implement that.<br></div></block=
quote><div><br></div><div>Apparently, this is a non-binding requirement of =
the standard. I think it can be relaxed without code breakage, right?</div>=
</div></blockquote></span><div><br>In the sense that code will still <i>fun=
ction</i>, sure.<br><br>But what about the sense of code doing what we&#39;=
ve told everyone it does? That implementation note in the standard, where i=
t says that implementations &quot;should&quot; only perform one allocation,=
 is really important. Saying that this optimization is the primary reason w=
hy `allocate_shared` exists is not overstating things. Note that while we h=
ave `make_unique`, we don&#39;t have `allocate_unqiue`.<br><br>We gauge the=
 quality of implementations based on them following that note. People both =
expect and <i>rely upon</i> this optimization. We do not want to break opti=
mizations that people have been relying on, even though their code technica=
lly still works. Just as we do not want to make changes to `basic_string` t=
hat make small-string optimizations illegal (we broke COW strings because t=
hat&#39;s not an optimization).<br><br>Such things would not &quot;break&qu=
ot; code in the sense of making it non-functional, but it would <i>certainl=
y</i> get people to stop using the standard library version.<br><br>This so=
rt of thinking has been applied to other things in the standard library. If=
 our `variant` type required implementers to double-buffer the internal dat=
a, certain people would <i>never</i> use it. For them, that&#39;s too much =
of a tradeoff for the minor benefit of exception safety. And you can hardly=
 blame them for wanting to avoid it for that reason.<br><br>Take this optim=
ization away, and lots of people with stop using the standard library share=
d_ptr in favor of either a home-grown shared_ptr or a home-grown intrusive_=
ptr. This is to nobody&#39;s benefit.<br><br></div><span class=3D""><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Apart from that, I&#=
39;m not telling anyone to use my implementation, I&#39;m just asking, whet=
her people like or dislike the functionality at all.</div></div></blockquot=
e></span><div><br>My point wasn&#39;t that your `make_shared` implementatio=
n didn&#39;t do the right thing. It&#39;s that it <b>cannot</b> implement t=
he optimization. And therefore, if we adopt this, then we are telling peopl=
e that the optimization no longer can be used.<br><br>This is not a feature=
 which is worth that cost. If you have need of=20
it, you can use your own `shared_ptr` type that provides this=20
functionality.<br><br></div><span class=3D""><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr">Personally, I don&#39;t like the idea of an object being able to c=
laim ownership of <i>itself</i>, even before it has finished being construc=
ted. That sounds very wrongly designed.<br></div></blockquote><div><br></di=
v><div>To some extent I can understand your worries.</div><div><b>You might=
 want to put it this way:</b></div><div>If you&#39;re not owned by any shar=
ed_ptr instance (yet), then you are effectively the owner of yourself.</div=
></div></blockquote></span><div><br>To own something, even with shared owne=
rship, means that you can delete it (or with shared ownership, terminate yo=
ur share of that ownership). But you cannot end the lifetime of an object w=
ho&#39;s lifetime has not started yet. And by C++&#39;s rules, an object&#3=
9;s lifetime does not begin until one of its constructors finishes.<br><br>=
Therefore, you cannot claim ownership of an object that is still being cons=
tructed. That would be a logical contradiction of one of these concepts.<br=
><br>So if you&#39;re claiming ownership of yourself in your own constructo=
r, then either you&#39;re doing something very wrong, or my idea of the con=
cept of &quot;ownership&quot; is confused.<br><br></div><span class=3D""><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>If a=
n instantiation of a class that derives from enable_shared_from_this is not=
 put into a shared_ptr later on,</div><div>all of it&#39;s methods that use=
 shared_from_this() will lead to UB as well.</div></div></blockquote></span=
><div><br>Not anymore; C++17 made a change here. You will get a `bad_weak_p=
tr` exception if you call `shared_from_this` on an object which was not bou=
nd to a `shared_ptr`.<br>=C2=A0</div><span class=3D""><blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div><b>This risk of unbound enable_sha=
red_from_this instances, was a trade-off that has already been accepted by =
introducing <i>enable_shared_from_this</i>.</b></div></div></blockquote></s=
pan><div><br>My point is not specifically the possibility of misuse. For me=
, it is the logic of the situation: what does it mean to have ownership of =
an object that does not yet exist?<br>=C2=A0</div><span class=3D""><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex">If a type has `enable_shared_=
from_this`, then it&#39;s possible that its constructor could create a new =
`shared_ptr` internally, which would allocate the control block.<br></block=
quote><div><br></div><div>The point of a possible implementation is, that <=
i>enable_shared_from_this </i>obviously has to allocate the control-block (=
reference-count-struct) and pass it to the shared_ptr once assigned.</div><=
/div></blockquote></span><div><br>That doesn&#39;t help `make/allocate_shar=
ed` to provide the required optimization. Who allocates it is ultimately <i=
>irrelevant</i>; what matters is that it gets allocated in the same memory =
as the type being constructed. And unless `enable_shared_from_this` actuall=
y has the control block within <i>itself</i>, there&#39;s no way to prevent=
 the allocation of a separate control block.<br><br>As for what I just ment=
ioned (`enable_shared_from_this` storing the control block), there was an e=
xtensive discussion about this sort <a href=3D"https://groups.google.com/a/=
isocpp.org/forum/#!topic/std-discussion/WF0gyN9g2mQ%5B101-125%5D" target=3D=
"_blank">of thing in another thread</a>. While it may or may not be possibl=
e in a theoretical sense, it would certainly not be possible for `enable_sh=
ared_from_this` as it currently stands to do it. This would require using a=
 new type, due in part to potentially having to give that type an allocator=
..<br>=C2=A0</div><span class=3D""><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div></div><div>Generally:</div><div>Please not just say.=
...</div><div><ul><li>it doesn&#39;t work. There is (nearly) always a soluti=
on, if you are just willing to find one.<br></li><li>it can be misused. Tha=
t is always the case, always. The question is, whether the risk of misuse o=
utweights the benefit?<br>...and as stated above, if they use=C2=A0<i>share=
d_from_this </i>on instances that will never be owned by a shared_ptr, that=
 will be a problem in the constructor as well.</li></ul><div>Dear Nicol, I&=
#39;m not your enemy and I don&#39;t force you to replace your opinion with=
 mine.</div><div>But I invite you to answer constructively.</div></div></di=
v></blockquote></span><div><br>What&#39;s unconstructive about what I said?=
 I explained the problems I saw in the proposal: that it doesn&#39;t allow =
`make/allocate_shared` to do their job correctly, and that it supports a pr=
ogramming construct that I find to be highly dubious. You may not agree wit=
h my arguments or positions, but that hardly makes them unconstructive.<br>=
<br>If you wish to prove point #1 wrong, all you need to do is provide an i=
mplementation where it can actually work. Just make sure that it works with=
 both `make_shared` <i>and</i> `allocate_shared`. Which means you&#39;ll ne=
ed to keep that allocator around and so forth.<br></div></div><span class=
=3D"">

<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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/53300081-cbc4-43fc-806b-bccb3ef053b3%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/5330=
0081-cbc4-43fc-<wbr>806b-bccb3ef053b3%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></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/CADbh%2BeQFk1dMMDW-02TFn4JUgc0-Cja%2B=
fh7rZ7aLGm8y1UZdzg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeQFk1=
dMMDW-02TFn4JUgc0-Cja%2Bfh7rZ7aLGm8y1UZdzg%40mail.gmail.com</a>.<br />

--001a1138fa2ac855cd0542b395fb--

.