220 7285 <9d55f4fd-9bfa-486b-9f94-a3647422f398@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Andrew Tomazos <andrewtomazos@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Predynamic Storage Duration
Date: Mon, 14 Oct 2013 01:24:32 -0700 (PDT)
Lines: 216
Approved: news@gmane.org
Message-ID: <9d55f4fd-9bfa-486b-9f94-a3647422f398@isocpp.org>
References: <6fabf6ab-eb9b-42a1-b4a4-deacb2d30ba1@isocpp.org>
 <CAOfiQqmHT4aKmTabn5jb-ikDfvwD=tu6LLobY-dVTqtVE2HpFQ@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_76_17550782.1381739072846"
X-Trace: ger.gmane.org 1381739072 19784 80.91.229.3 (14 Oct 2013 08:24:32 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 14 Oct 2013 08:24:32 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBD5KHQXXWYPRBQWU52JAKGQES2RIIQQ@isocpp.org Mon Oct 14 10:24:36 2013
Return-path: <std-proposals+bncBD5KHQXXWYPRBQWU52JAKGQES2RIIQQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ie0-f199.google.com ([209.85.223.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBD5KHQXXWYPRBQWU52JAKGQES2RIIQQ@isocpp.org>)
	id 1VVdS7-0006Zt-LV
	for gclcip-std-proposals@m.gmane.org; Mon, 14 Oct 2013 10:24:35 +0200
Original-Received: by mail-ie0-f199.google.com with SMTP id qd12sf9920437ieb.2
        for <gclcip-std-proposals@m.gmane.org>; Mon, 14 Oct 2013 01:24:34 -0700 (PDT)
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
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=aXWXBM9MfkRJJbXh1+/Dbbn7EGxDLSr53o/7ikyqBOU=;
        b=U6pyatNV8Ncg52TIs3VLeJAZxmK+8CXYiUXeXZZEyFQRUbw+i8Aj3ubq4XzAM3Zya3
         HXbr8Z0DYzmPtcYBuxMdPAl3ZYWC5etzXu9GB7mvCT7hcZNb3xOVmT8+K6Sw/J2+lRvR
         m+9qtP3tcSMi+bYJ/pwQ2LQ/sn3hOO4eXTbUkBjnPRvzqe41yPCJvBI3BOdf7REF8Eau
         jJzNp/N6rcyBVBQKrH0ThYSBfu8m2mPjt17mJKLp03N+qQrhsSTcS3IEqMcrQ8A+a220
         g3hP9enTikSU600FwoxUUFH+wtFFJEdp+hOX1tmzBduO6oER/sc1EPzfZGcN8koLN2Af
         Zj+w==
X-Received: by 10.182.53.165 with SMTP id c5mr11678983obp.0.1381739074606;
        Mon, 14 Oct 2013 01:24:34 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.118.6 with SMTP id ki6ls1350465igb.20.gmail; Mon, 14 Oct
 2013 01:24:34 -0700 (PDT)
X-Received: by 10.50.98.4 with SMTP id ee4mr324962igb.5.1381739074123;
        Mon, 14 Oct 2013 01:24:34 -0700 (PDT)
In-Reply-To: <CAOfiQqmHT4aKmTabn5jb-ikDfvwD=tu6LLobY-dVTqtVE2HpFQ@mail.gmail.com>
X-Original-Sender: andrewtomazos@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: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:7285
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/7285>

------=_Part_76_17550782.1381739072846
Content-Type: text/plain; charset=ISO-8859-1

On Monday, October 14, 2013 7:05:02 AM UTC+2, Richard Smith wrote:
>
> Supporting allocate-during-translation/deallocate-during-runtime is pretty 
> tricky from an implementation perspective, especially since the usual 
> allocation and deallocation functions can be replaced. We cannot know in 
> advance what layout a custom heap will take in memory, so we cannot 
> prepopulate a "preheap" as a static data structure and expect a replacement 
> deallocation function to be able to cope with it. (Also, 
> practically-speaking, the compiler vendor typically does not know how the 
> library vendor will choose to implement the heap.) This can be mitigated by 
> requiring the implementation to repeatedly call the (replacement) 
> ::operator new to allocate the preheap during program startup, but that 
> removes a lot of the value of the proposal.
>

I wouldn't be so hasty to discard your "repeatedly calling new on the 
preheap at load-time" idea.  Even with such a workaround, I think it would 
still be useful to be able to do 
"allocate-during-translation/deallocate-during-runtime".
 

> More difficult is supporting types like std::vector, which want to 
> manipulate bytes of storage, not just allocated objects. Constant 
> expression evaluation very deliberately does not allow accessing the object 
> representation of a type (that is, in many cases, impossible to implement 
> during translation, because -- for instance -- the bit pattern of types 
> containing pointers is not yet known). A suitably careful implementation of 
> std::vector<T> could probably sidestep this issue, perhaps through 'new 
> Uninitialized<T>[N];', where Uninitialized is a union type containing T, 
> but it's unlikely that any such approach would be compatible with the other 
> constraints on std::vector, such as guaranteed array-like contiguous 
> allocation (so data()[N] works) and use of a custom allocator.
>
 
What you are highlighting here are additional problems on top of the 
dynamic allocation issue to making `std::vector` a literal type.  I agree 
with your assessment, however given the proposed feature I think it may be 
possible for a library author to implement a `literal_vector` class with a 
similar interface to vector that sidesteps these issues.  We are seeing 
similar things for `std::array` where people are defining their own 
`literal_array` classes to sidestep some of the existing interface issues.  
The `std::vector` issues are much larger as you have pointed out, but 
perhaps they can be solved with additional future relaxations.  I think we 
can agree that it would worthwhile for `std::vector` to be literal if 
possible, and in the interim implementing your own `literal_vector` class 
would be nice to be able to do too.

Having said the above, I did come up with a design for this which I believe 
> works. It's somewhat more restricted than what you were describing, but is 
> enough to get many uses of dynamic storage to work:
>
>  * In order to support deleting objects in a destructor, allow destructors 
> to be marked 'constexpr', and implicitly mark all trivial destructors as 
> 'constexpr'. Require a literal type to have a constexpr destructor rather 
> than a trivial one.
>
>  * Allow new-expressions and delete-expressions in core constant 
> expressions. The rules for constant expressions are unchanged, so they can 
> still only refer to objects of static storage duration (not of automatic, 
> thread, or [now possible] dynamic storage duration). This allows temporary 
> usage of dynamic allocation during constant expression evaluation, but does 
> not allow it to leak outside the computation. Under N3664, and 
> implementation is permitted to elide this allocation rather than actually 
> invoking the allocation/deallocation functions (and during constant 
> expression evaluation, it would be expected to do so).
>
>  * Objects declared 'constexpr' can have non-trivial (but constexpr) 
> destructors, but only if the evaluation of the destructor on the object is 
> itself a constant expression (since the object is 'const', we can check 
> this during translation). For such an object, we allow subobjects to be 
> pointers or references to dynamic storage, so long as the evaluation of the 
> destructor deletes the storage. Additionally, make it undefined behavior to 
> delete such objects outside of the destructor.
>
 
I think I see where you are going here, but why couldn't a pointer to a 
predynamic object be an address constant expression as per a pointer to a 
static storage duration object.

When a constexpr-specified object of static storage duration is encountered 
during translation, the implementation must track its value and pointers to 
it.  The pointers are in symbol+addend form, and the constant expression 
rules are setup to support this.  Handling predynamic objects in the 
preheap should be no different to handling objects of static storage 
duration in this regard.

At the end of translation the preheap objects could be stored in the 
program image in the same way as static storage duration objects.  Then at 
load-time as you suggest we could call operator new on each preheap object 
copying it into the heap.  Pointers to preheap objects are then relocated 
as for pointers to static storage duration objects.

This doesn't address mutability of preheap objects, but I don't see how 
this is any different to mutability of local variables in constexpr 
functions.  Implementations already have to deal with that for automatic 
storage duration objects, so why couldn't they deal with it the same way 
for predynamic storage duration objects.
-Andrew

-- 

--- 
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_76_17550782.1381739072846
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, October 14, 2013 7:05:02 AM UTC+2, Richard Smit=
h 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">Suppo=
rting allocate-during-translation/<wbr>deallocate-during-runtime is pretty =
tricky from an implementation perspective, especially since the usual alloc=
ation and deallocation functions can be replaced. We cannot know in advance=
 what layout a custom heap will take in memory, so we cannot prepopulate a =
"preheap" as a static data structure and expect a replacement deallocation =
function to be able to cope with it. (Also, practically-speaking, the compi=
ler vendor typically does not know how the library vendor will choose to im=
plement the heap.) This can be mitigated by requiring the implementation to=
 repeatedly call the (replacement) ::operator new to allocate the preheap d=
uring program startup, but that removes a lot of the value of the proposal.=
</div></blockquote><div><br>I wouldn't be so hasty to discard your "repeate=
dly calling new on the preheap at load-time" idea.&nbsp; Even with such a w=
orkaround, I think it would still be useful to be able to do "allocate-duri=
ng-translation/deallocate-during-runtime".<br></div><div>&nbsp;</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>Mor=
e difficult is supporting types like std::vector, which want to manipulate =
bytes of storage, not just allocated objects. Constant expression evaluatio=
n very deliberately does not allow accessing the object representation of a=
 type (that is, in many cases, impossible to implement during translation, =
because -- for instance -- the bit pattern of types containing pointers is =
not yet known). A suitably careful implementation of std::vector&lt;T&gt; c=
ould probably sidestep this issue, perhaps through 'new Uninitialized&lt;T&=
gt;[N];', where Uninitialized is a union type containing T, but it's unlike=
ly that any such approach would be compatible with the other constraints on=
 std::vector, such as guaranteed array-like contiguous allocation (so data(=
)[N] works) and use of a custom allocator.</div>
</div></blockquote><div>&nbsp;<br>What you are highlighting here are additi=
onal problems on top of the dynamic allocation issue to making `std::vector=
` a literal type.&nbsp; I agree with your assessment, however given the pro=
posed feature I think it may be possible for a library author to implement =
a `literal_vector` class with a similar interface to vector that sidesteps =
these issues.&nbsp; We are seeing similar things for `std::array` where peo=
ple are defining their own `literal_array` classes to sidestep some of the =
existing interface issues.&nbsp; The `std::vector` issues are much larger a=
s you have pointed out, but perhaps they can be solved with additional futu=
re relaxations.&nbsp; I think we can agree that it would worthwhile for `st=
d::vector` to be literal if possible, and in the interim implementing your =
own `literal_vector` class would be nice to be able to do too.<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Having =
said the above, I did come up with a design for this which I believe works.=
 It's somewhat more restricted than what you were describing, but is enough=
 to get many uses of dynamic storage to work:</div>
<div><br></div><div>&nbsp;* In order to support deleting objects in a destr=
uctor, allow destructors to be marked 'constexpr', and implicitly mark all =
trivial destructors as 'constexpr'. Require a literal type to have a conste=
xpr destructor rather than a trivial one.</div>
<div><br></div><div>&nbsp;* Allow new-expressions and delete-expressions in=
 core constant expressions. The rules for constant expressions are unchange=
d, so they can still only refer to objects of static storage duration (not =
of automatic, thread, or [now possible] dynamic storage duration). This all=
ows temporary usage of dynamic allocation during constant expression evalua=
tion, but does not allow it to leak outside the computation. Under N3664, a=
nd implementation is permitted to elide this allocation rather than actuall=
y invoking the allocation/deallocation functions (and during constant expre=
ssion evaluation, it would be expected to do so).</div>
<div><br></div><div>&nbsp;* Objects declared 'constexpr' can have non-trivi=
al (but constexpr) destructors, but only if the evaluation of the destructo=
r on the object is itself a constant expression (since the object is 'const=
', we can check this during translation). For such an object, we allow subo=
bjects to be pointers or references to dynamic storage, so long as the eval=
uation of the destructor deletes the storage. Additionally, make it undefin=
ed behavior to delete such objects outside of the destructor.</div>
</div></blockquote><div>&nbsp;<br>I think I see where you are going here, b=
ut why couldn't a pointer to a predynamic object be an address constant exp=
ression as per a pointer to a static storage duration object.<br><br>When a=
 constexpr-specified object of static storage duration is encountered durin=
g translation, the implementation must track its value and pointers to it.&=
nbsp; The pointers are in symbol+addend form, and the constant expression r=
ules are setup to support this.&nbsp; Handling predynamic objects in the pr=
eheap should be no different to handling objects of static storage duration=
 in this regard.<br><br>At the end of translation the preheap objects could=
 be stored in the program image in the same way as static storage duration =
objects.&nbsp; Then at load-time as you suggest we could call operator new =
on each preheap object copying it into the heap.&nbsp; Pointers to preheap =
objects are then relocated as for pointers to static storage duration objec=
ts.<br><br>This doesn't address mutability of preheap objects, but I don't =
see how this is any different to mutability of local variables in constexpr=
 functions.&nbsp; Implementations already have to deal with that for automa=
tic storage duration objects, so why couldn't they deal with it the same wa=
y for predynamic storage duration objects.<br>-Andrew<br><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_76_17550782.1381739072846--

.
