220 34982 <89c7d198-0eec-4099-ba31-bad92706ebae@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: Contra P0722R0 "destroying operator-delete"
Date: Tue, 17 Oct 2017 09:39:03 -0700 (PDT)
Lines: 263
Approved: news@gmane.org
Message-ID: <89c7d198-0eec-4099-ba31-bad92706ebae@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_19517_1569868226.1508258343528"
X-Trace: blaine.gmane.org 1508258345 337 195.159.176.226 (17 Oct 2017 16:39:05 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 17 Oct 2017 16:39:05 +0000 (UTC)
Cc: Andrew Hunter <ahh@google.com>, Richard Smith <richardsmith@google.com>
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDLZJYWNDQIKRZEYZ4CRUBDCMBU4G@isocpp.org Tue Oct 17 18:39:00 2017
Return-path: <std-proposals+bncBDLZJYWNDQIKRZEYZ4CRUBDCMBU4G@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f70.google.com ([209.85.213.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDLZJYWNDQIKRZEYZ4CRUBDCMBU4G@isocpp.org>)
	id 1e4UtO-0007ZS-DR
	for gclcip-std-proposals@m.gmane.org; Tue, 17 Oct 2017 18:38:58 +0200
Original-Received: by mail-vk0-f70.google.com with SMTP id j2sf935006vki.15
        for <gclcip-std-proposals@m.gmane.org>; Tue, 17 Oct 2017 09:39:06 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=joH4YOxuJmSA9U8KhP8BL7nosumFjUTlmTTkTqyfH8U=;
        b=Qnxkh3JBWWtgSsUQFZOmszenHBPVnGsBdINp5wmeVqrN5oaFLgqNIv9uaJFJ3UEoPt
         MIBQ7xT+/Y34hTHIkGvl8NLYOiLDZ691GdgZZIx3cm0/T6YOyUswDJKlnvqzAqy9+4sc
         aLolaZyimR1kvwBG+DK3Q5HLa8of4Btp0fAqKf6yWroaHWvUbj9+hublIYQJ5zrjIGy6
         ayhDU490CSjSgFq4VWLXZukYZfLJE7wqrq3QKDvGqbuT4Sdm9ExScOhgU1n5pCz7r4Yj
         hCWWuMcjE/zuiYvasuO2Ce4nUX9frJrsSQVS9Ho/MNF6WEHaSf5xFHjuQnvYJJTbxxbl
         oP9A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=joH4YOxuJmSA9U8KhP8BL7nosumFjUTlmTTkTqyfH8U=;
        b=Q+jBHg0G/KzJe2K14jqc3Vo85ZXCADZBZnQCrJB25C7oZxXX9kOQulLtqL3PYx5n3P
         b6Q1TNGQW9cYoc0Y12MqSpbVJynKZY3ifGQrkFN4VLWO6JIPbheU7XM9NlZVY4f2QDlC
         SpA/6gWohXkOg/wLW2rra4NS9UXSmX8Kjulnx5hMH884YnYhMw1PVH+rD6Pucq/TKnGZ
         4b899G4+EfFv5+UjYhxFSsyFhaTGxMQ08X46TQ564FBMhtfU5g2rRswIc12Ntnn150Gr
         fzAVZlHqvX4QdUzqUlx8f+WdYGpSFHIfnlowGcda7BqevTd3LdTqD2bwuQLW4s66QRjq
         Oc5w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:cc:message-id: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=joH4YOxuJmSA9U8KhP8BL7nosumFjUTlmTTkTqyfH8U=;
        b=VPg2GrjVo+33IF3+gAEZ0fnPDqDVEVawk/RDH7SdCZjjqG1gPaljFplbm8mgOvxCmW
         fTvkA4G4eMlrgV8v7foH7jKiJbcFYvRwi7FpERfCumJ1QLfOax18yhV1X04ydadPRsuh
         fX5my0FuKufOnPTnRg45cQrScbyjpW4Twql7ybBcqP+sFxbe5/eqsiVVxOxCU3EBler7
         sZgJUHjyguoFFbJD3Rpi4wfcWIEYh88p9pW2xhM3l3h0Bms/Je5anaNIgX/PsAt/9rRi
         RlRcxvU+txcmtOQ3e3NuYkOiDU/Ncvn1cLk2Vu45LKNvaU5YLmQd0T228z+owzXYx2xb
         rwMA==
X-Gm-Message-State: AMCzsaUS+LkHCxA4DwKyVzSdgAuCtfKbhwn5Ygi7LKnDZN4CLtU6vFeI
	G8qfX7RlVYqAguXzWZsr7kFhWg==
X-Google-Smtp-Source: AOwi7QAiJ8/O8utxE1wvnWL79DoylJE7Q5zxQldQ6F5AiX/WEFiaM1cyTl+E3ol975XV4SwYmLCKuA==
X-Received: by 10.176.82.245 with SMTP id w50mr7513683uaw.102.1508258345529;
        Tue, 17 Oct 2017 09:39:05 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.168.147 with SMTP id r141ls394732vke.8.gmail; Tue, 17 Oct
 2017 09:39:04 -0700 (PDT)
X-Received: by 10.31.161.87 with SMTP id k84mr1030716vke.7.1508258343982;
        Tue, 17 Oct 2017 09:39:03 -0700 (PDT)
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:34982
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/34982>

------=_Part_19517_1569868226.1508258343528
Content-Type: multipart/alternative; 
	boundary="----=_Part_19518_1262803990.1508258343528"

------=_Part_19518_1262803990.1508258343528
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

This is related to Richard Smith and Andrew Hunter's P0722R0 "Controlling=
=20
destruction in delete expressions"=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0722r0.htm>.
The paper begins this way:

Consider the following class:

class inlined_fixed_string {
  public:
   inlined_fixed_string() =3D delete;
   const size_t size() const { return size_; }

   const char *data() const {
     return static_cast<const char *>(this + 1);
   }

   // operator[], etc, with obvious implementations

   inlined_fixed_string *Make(const std::string &data) {
     size_t full_size =3D sizeof(inlined_fixed_string) + data.size();
     return new(::operator new(full_size))
                  inlined_fixed_string(data.size(), data.c_str());
   }

  private:
   inlined_fixed_string(size_t size, const char *data) : size_(size) {
     memcpy(data(), data, size);
   }
   size_t size_;
};

This defines what is (effectively) a variable-sized object, using that to
implement an array of size determined at runtime while saving a pointer
indirection. (Note: this pattern is simpler (and generally written) with
flexible array members, despite their being nonstandard.)

However, what happens when we delete such a string s in the presence of
sized-delete?


Well, you get misbehavior, of course. Syntactically, C++ allows you to use=
=20
"delete" on any pointer; but semantically, you should use "delete" only on=
=20
pointers that were originally obtained from "new". And in your case, you=20
didn't obtain the pointer from "new"; you obtained it from the public=20
factory function "Make".
This code is broken because it has a public "Make" factory and private=20
constructor, but it is missing a public "Destroy" factory and private=20
destructor. If you rewrite it to use that idiom, then the problem goes away=
..
The corrected code looks like this=20
<https://wandbox.org/permlink/YMYEwUFZtLlHeHEo>, and requires absolutely no=
=20
core language changes.

class inlined_fixed_string {
  public:
   inlined_fixed_string() =3D delete;
   size_t size() const { return size_; }

   char *data() {
     return reinterpret_cast<char *>(this + 1);
   }

   // operator[], etc, with obvious implementations

   static inlined_fixed_string *Make(const std::string &data) {
     size_t full_size =3D sizeof(inlined_fixed_string) + data.size();
     return new(::operator new(full_size))
                  inlined_fixed_string(data.size(), data.c_str());
   }

   static void Destroy(inlined_fixed_string *p) {
     size_t full_size =3D sizeof(*p) + p->size();
     p->~inlined_fixed_string();
     ::operator delete(p, full_size);
   }
  private:
   inlined_fixed_string(size_t n, const char *s) : size_(n) {
     memcpy(data(), s, n);
   }
   ~inlined_fixed_string() {}
   size_t size_;
};

int main() {
    inlined_fixed_string *s =3D inlined_fixed_string::Make("hello world");
    inlined_fixed_string::Destroy(s);

    std::shared_ptr<inlined_fixed_string> p(inlined_fixed_string::Make("hel=
lo shared"), inlined_fixed_string::Destroy);
}



That said, if you do pursue "destroy and delete in one atomic operation",=
=20
it will be of especial interest to the garbage-collection and RCU folks.=20
Louis Dionne is interested in building a deferred_reclamation_allocator<T>=
=20
that can defer calls to destroy() and deallocate() in pairs, which is=20
essentially the primitive you wanted to provide in P0722R0. (But again, you=
=20
don't need P0722R0, and I'd much much rather the Committee not pursue it.=
=20
Nobody understands new/delete as it is; let's not make the situation even=
=20
worse out of a misbegotten wish to "delete" objects we haven't "new"ed.)=20

Incidentally, if the individual words didn't already have domain-specific=
=20
meanings, I would love to describe inlined_fixed_string's semantics in=20
terms of the Make "factory function" and the Destroy "glue factory=20
function". ;)

my $.02,
=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/89c7d198-0eec-4099-ba31-bad92706ebae%40isocpp.or=
g.

------=_Part_19518_1262803990.1508258343528
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is related to Richard Smith and Andrew Hunter&#39;s <=
a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0722r0.h=
tm">P0722R0 &quot;Controlling destruction in delete expressions&quot;</a>.<=
br>The paper begins this way:<div><br></div><div><pre style=3D"color: rgb(0=
, 0, 0);">Consider the following class:

class inlined_fixed_string {
  public:
   inlined_fixed_string() =3D delete;
   const size_t size() const { return size_; }

   const char *data() const {
     return static_cast&lt;const char *&gt;(this + 1);
   }

   // operator[], etc, with obvious implementations

   inlined_fixed_string *Make(const std::string &amp;data) {
     size_t full_size =3D sizeof(inlined_fixed_string) + data.size();
     return new(::operator new(full_size))
                  inlined_fixed_string(data.size(), data.c_str());
   }

  private:
   inlined_fixed_string(size_t size, const char *data) : size_(size) {
     memcpy(data(), data, size);
   }
   size_t size_;
};

This defines what is (effectively) a variable-sized object, using that to
implement an array of size determined at runtime while saving a pointer
indirection. (Note: this pattern is simpler (and generally written) with
flexible array members, despite their being nonstandard.)

However, what happens when we delete such a string s in the presence of
sized-delete?</pre><br>Well, you get misbehavior, of course. Syntactically,=
 C++ allows you to use &quot;delete&quot; on any pointer; but semantically,=
 you should use &quot;delete&quot; only on pointers that were originally ob=
tained from &quot;new&quot;. And in your case, you didn&#39;t obtain the po=
inter from &quot;new&quot;; you obtained it from the public factory functio=
n &quot;Make&quot;.</div><div>This code is broken because it has a public &=
quot;Make&quot; factory and private constructor, but it is missing a public=
 &quot;Destroy&quot; factory and private destructor. If you rewrite it to u=
se that idiom, then the problem goes away.</div><div><a href=3D"https://wan=
dbox.org/permlink/YMYEwUFZtLlHeHEo">The corrected code looks like this</a>,=
 and requires absolutely no core language changes.</div><div><br></div><div=
><pre style=3D"color: rgb(0, 0, 0);">class inlined_fixed_string {
  public:
   inlined_fixed_string() =3D delete;
   size_t size() const { return size_; }

   char *data() {
     return reinterpret_cast&lt;char *&gt;(this + 1);
   }

   // operator[], etc, with obvious implementations

   static inlined_fixed_string *Make(const std::string &amp;data) {
     size_t full_size =3D sizeof(inlined_fixed_string) + data.size();
     return new(::operator new(full_size))
                  inlined_fixed_string(data.size(), data.c_str());
   }

   static void Destroy(inlined_fixed_string *p) {
     size_t full_size =3D sizeof(*p) + p-&gt;size();
     p-&gt;~inlined_fixed_string();
     ::operator delete(p, full_size);
   }
  private:
   inlined_fixed_string(size_t n, const char *s) : size_(n) {
     memcpy(data(), s, n);
   }
   ~inlined_fixed_string() {}
   size_t size_;
};

int main() {
    inlined_fixed_string *s =3D inlined_fixed_string::Make(&quot;hello worl=
d&quot;);
    inlined_fixed_string::Destroy(s);

    std::shared_ptr&lt;inlined_fixed_string&gt; p(inlined_fixed_string::Mak=
e(&quot;hello shared&quot;), inlined_fixed_string::Destroy);
}<br></pre><pre style=3D"color: rgb(0, 0, 0);"><br></pre><pre style=3D"colo=
r: rgb(0, 0, 0);"><span style=3D"color: rgb(34, 34, 34); font-family: Arial=
, Helvetica, sans-serif;"><br></span></pre>That said, if you do pursue &quo=
t;destroy and delete in one atomic operation&quot;, it will be of especial =
interest to the garbage-collection and RCU folks. Louis Dionne is intereste=
d in building a deferred_reclamation_allocator&lt;T&gt; that can defer call=
s to destroy() and deallocate() in pairs, which is essentially the primitiv=
e you wanted to provide in P0722R0. (But again, you don&#39;t need P0722R0,=
 and I&#39;d much much rather the Committee not pursue it. Nobody understan=
ds new/delete as it is; let&#39;s not make the situation even worse out of =
a misbegotten wish to &quot;delete&quot; objects we haven&#39;t &quot;new&q=
uot;ed.) <br><br>Incidentally, if the individual words didn&#39;t already h=
ave domain-specific meanings, I would love to describe inlined_fixed_string=
&#39;s semantics in terms of the Make &quot;factory function&quot; and the =
Destroy &quot;glue factory function&quot;. ;)<br><br>my $.02,<br>=E2=80=93A=
rthur</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/89c7d198-0eec-4099-ba31-bad92706ebae%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/89c7d198-0eec-4099-ba31-bad92706ebae=
%40isocpp.org</a>.<br />

------=_Part_19518_1262803990.1508258343528--

------=_Part_19517_1569868226.1508258343528--

.
