Topic: Predynamic Storage Duration


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sun, 13 Oct 2013 21:25:29 -0700 (PDT)
Raw View
------=_Part_10_23753554.1381724729902
Content-Type: text/plain; charset=ISO-8859-1

I want this:

    std::string s = "foo";
    std::vector<int> v = {1,2,3};

to be as efficient as this:

    char s[] = "foo";
    int v[] = {1,2,3};

and I want to write this:

    constexpr std::vector<int> f(...)
    {
        std::vector<int> v;

        for (...)
        {
             ...

             v.push_back(v);
        }

        return v;
    }

Basically, I want std::string, std::vector and similar classes to be
literal types.

The main reason they cannot currently be literal types is because they need
to allocate objects of dynamic storage duration, and the heap isn't
available during translation.

So here are the proposed changes:

- Allow new expressions and delete expressions within constexpr functions
(provided the operands are of literal type.)

- A new expression evaluated within a constexpr function in
constant-context returns a pointer to an object of predynamic storage
duration

- A delete expression evaluated within a constexpr function in
constant-context deletes an object of predynamic storage duration

- A delete expression evaluated at run-time deletes an object of either
predynamic or dynamic storage duration

Essentially, predynamic storage duration starts during translation and can
end as late as run-time.

During translation when evaluating a new expression within a constexpr
function the implementation allocates the object within a memory pool
(using whatever internal system it uses to hold variables of literal type)
we'll call the preheap.  When encountering a delete expression in a
constexpr function it deletes the operand from the preheap.  Any predynamic
objects left over in the preheap after translation has completed are
arranged into the program image in a .preheap section.  When the program
loads the .preheap section is copied into memory and serves as part of the
initial state of the run-time heap.

    constexpr int* f()
    {
        int a[] = {1,2,3};

        int* b = new int[3];  // predynamic object allocated during
translation

        for (size_t i = 0; i < 3; i++)
            b[i] = a[i];

        return b;
     }

     constexpr int* p = f(); // f called duration translation, returns
pointer to predynamic object

     int main()
     {
         delete p; // deletes predynamic object at runtime
     }

Feedback/thoughts appreciated.


--

---
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_10_23753554.1381724729902
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I want this:<br><br>&nbsp;&nbsp;&nbsp; std::string s =3D "=
foo";<br>&nbsp;&nbsp;&nbsp; std::vector&lt;int&gt; v =3D {1,2,3};<br><br>to=
 be as efficient as this:<br><br>&nbsp;&nbsp;&nbsp; char s[] =3D "foo";<br>=
&nbsp;&nbsp;&nbsp; int v[] =3D {1,2,3};<br><br>and I want to write this:<br=
><br>&nbsp;&nbsp;&nbsp; constexpr std::vector&lt;int&gt; f(...)<br>&nbsp;&n=
bsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::vector&lt;i=
nt&gt; v;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (...)<br>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br><br>&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; v.push_back(v);<br>&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; return v;<br>&nbsp;&nbsp;&nbsp; }<br><br>Basically, I want=
 std::string, std::vector and similar classes to be literal types.<br><br>T=
he main reason they cannot currently be literal types is because they need =
to allocate objects of dynamic storage duration, and the heap isn't availab=
le during translation.<br><br>So here are the proposed changes:<br><br>- Al=
low new expressions and delete expressions within constexpr functions (prov=
ided the operands are of literal type.)<br><br>- A new expression evaluated=
 within a constexpr function in constant-context returns a pointer to an ob=
ject of predynamic storage duration<br><br>- A delete expression evaluated =
within a constexpr function in constant-context deletes an object of predyn=
amic storage duration<br><br>- A delete expression evaluated at run-time de=
letes an object of either predynamic or dynamic storage duration<br><br>Ess=
entially, predynamic storage duration starts during translation and can end=
 as late as run-time.<br><br>During translation when evaluating a new expre=
ssion within a constexpr function the implementation allocates the object w=
ithin a memory pool (using whatever internal system it uses to hold variabl=
es of literal type) we'll call the preheap.&nbsp; When encountering a delet=
e expression in a constexpr function it deletes the operand from the prehea=
p.&nbsp; Any predynamic objects left over in the preheap after translation =
has completed are arranged into the program image in a .preheap section.&nb=
sp; When the program loads the .preheap section is copied into memory and s=
erves as part of the initial state of the run-time heap.<br><br>&nbsp;&nbsp=
;&nbsp; constexpr int* f()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp; int a[] =3D {1,2,3};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; int* b =3D new int[3];&nbsp; // predynamic object allocat=
ed during translation<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for=
 (size_t i =3D 0; i &lt; 3; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; b[i] =3D a[i];<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; return b;<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbs=
p;&nbsp;&nbsp; constexpr int* p =3D f(); // f called duration translation, =
returns pointer to predynamic object<br><br>&nbsp;&nbsp;&nbsp;&nbsp; int ma=
in()<br>&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; delete p; // deletes predynamic object at runtime<br>&nbsp;&nbs=
p;&nbsp;&nbsp; }<br><br>Feedback/thoughts appreciated.<br><br><br></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_10_23753554.1381724729902--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Sun, 13 Oct 2013 21:53:05 -0700
Raw View
--047d7b2e4edacd584c04e8ac406c
Content-Type: text/plain; charset=ISO-8859-1

I can't think of a real world use case where this would have a significant
performance impact, and it adds significant complexity penalties into the
core language.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com


On Sun, Oct 13, 2013 at 9:25 PM, Andrew Tomazos <andrewtomazos@gmail.com>wrote:

> I want this:
>
>     std::string s = "foo";
>     std::vector<int> v = {1,2,3};
>
> to be as efficient as this:
>
>     char s[] = "foo";
>     int v[] = {1,2,3};
>
> and I want to write this:
>
>     constexpr std::vector<int> f(...)
>     {
>         std::vector<int> v;
>
>         for (...)
>         {
>              ...
>
>              v.push_back(v);
>         }
>
>         return v;
>     }
>
> Basically, I want std::string, std::vector and similar classes to be
> literal types.
>
> The main reason they cannot currently be literal types is because they
> need to allocate objects of dynamic storage duration, and the heap isn't
> available during translation.
>
> So here are the proposed changes:
>
> - Allow new expressions and delete expressions within constexpr functions
> (provided the operands are of literal type.)
>
> - A new expression evaluated within a constexpr function in
> constant-context returns a pointer to an object of predynamic storage
> duration
>
> - A delete expression evaluated within a constexpr function in
> constant-context deletes an object of predynamic storage duration
>
> - A delete expression evaluated at run-time deletes an object of either
> predynamic or dynamic storage duration
>
> Essentially, predynamic storage duration starts during translation and can
> end as late as run-time.
>
> During translation when evaluating a new expression within a constexpr
> function the implementation allocates the object within a memory pool
> (using whatever internal system it uses to hold variables of literal type)
> we'll call the preheap.  When encountering a delete expression in a
> constexpr function it deletes the operand from the preheap.  Any predynamic
> objects left over in the preheap after translation has completed are
> arranged into the program image in a .preheap section.  When the program
> loads the .preheap section is copied into memory and serves as part of the
> initial state of the run-time heap.
>
>     constexpr int* f()
>     {
>         int a[] = {1,2,3};
>
>         int* b = new int[3];  // predynamic object allocated during
> translation
>
>         for (size_t i = 0; i < 3; i++)
>             b[i] = a[i];
>
>         return b;
>      }
>
>      constexpr int* p = f(); // f called duration translation, returns
> pointer to predynamic object
>
>      int main()
>      {
>          delete p; // deletes predynamic object at runtime
>      }
>
> Feedback/thoughts appreciated.
>
>
>  --
>
> ---
> 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/.
>

--

---
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/.

--047d7b2e4edacd584c04e8ac406c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I can&#39;t think of a real world use case where this woul=
d have a significant performance impact, and it adds significant complexity=
 penalties into the core language.</div><div class=3D"gmail_extra"><br clea=
r=3D"all">

<div><div dir=3D"ltr"><div>Billy O&#39;Neal</div><div><a href=3D"https://bi=
tbucket.org/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</=
a></div><div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" t=
arget=3D"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div>

<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sun, Oct 13, 2013 at 9:25 PM, Andrew =
Tomazos <span dir=3D"ltr">&lt;<a href=3D"mailto:andrewtomazos@gmail.com" ta=
rget=3D"_blank">andrewtomazos@gmail.com</a>&gt;</span> wrote:<br><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex">

<div dir=3D"ltr">I want this:<br><br>=A0=A0=A0 std::string s =3D &quot;foo&=
quot;;<br>=A0=A0=A0 std::vector&lt;int&gt; v =3D {1,2,3};<br><br>to be as e=
fficient as this:<br><br>=A0=A0=A0 char s[] =3D &quot;foo&quot;;<br>=A0=A0=
=A0 int v[] =3D {1,2,3};<br><br>

and I want to write this:<br><br>=A0=A0=A0 constexpr std::vector&lt;int&gt;=
 f(...)<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 std::vector&lt;int&gt; v;<b=
r><br>=A0=A0=A0=A0=A0=A0=A0 for (...)<br>=A0=A0=A0=A0=A0=A0=A0 {<br>=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ...<br><br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 v.push_back(v);<br>
=A0=A0=A0=A0=A0=A0=A0 }<br>
<br>=A0=A0=A0=A0=A0=A0=A0 return v;<br>=A0=A0=A0 }<br><br>Basically, I want=
 std::string, std::vector and similar classes to be literal types.<br><br>T=
he main reason they cannot currently be literal types is because they need =
to allocate objects of dynamic storage duration, and the heap isn&#39;t ava=
ilable during translation.<br>

<br>So here are the proposed changes:<br><br>- Allow new expressions and de=
lete expressions within constexpr functions (provided the operands are of l=
iteral type.)<br><br>- A new expression evaluated within a constexpr functi=
on in constant-context returns a pointer to an object of predynamic storage=
 duration<br>

<br>- A delete expression evaluated within a constexpr function in constant=
-context deletes an object of predynamic storage duration<br><br>- A delete=
 expression evaluated at run-time deletes an object of either predynamic or=
 dynamic storage duration<br>

<br>Essentially, predynamic storage duration starts during translation and =
can end as late as run-time.<br><br>During translation when evaluating a ne=
w expression within a constexpr function the implementation allocates the o=
bject within a memory pool (using whatever internal system it uses to hold =
variables of literal type) we&#39;ll call the preheap.=A0 When encountering=
 a delete expression in a constexpr function it deletes the operand from th=
e preheap.=A0 Any predynamic objects left over in the preheap after transla=
tion has completed are arranged into the program image in a .preheap sectio=
n.=A0 When the program loads the .preheap section is copied into memory and=
 serves as part of the initial state of the run-time heap.<br>

<br>=A0=A0=A0 constexpr int* f()<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 in=
t a[] =3D {1,2,3};<br><br>=A0=A0=A0=A0=A0=A0=A0 int* b =3D new int[3];=A0 /=
/ predynamic object allocated during translation<br><br>=A0=A0=A0=A0=A0=A0=
=A0 for (size_t i =3D 0; i &lt; 3; i++)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 b[i] =3D a[i];<br>

<br>=A0=A0=A0=A0=A0=A0=A0 return b;<br>=A0=A0=A0=A0 }<br><br>=A0=A0=A0=A0 c=
onstexpr int* p =3D f(); // f called duration translation, returns pointer =
to predynamic object<br><br>=A0=A0=A0=A0 int main()<br>=A0=A0=A0=A0 {<br>=
=A0=A0=A0=A0=A0=A0=A0=A0 delete p; // deletes predynamic object at runtime<=
br>

=A0=A0=A0=A0 }<br><br>Feedback/thoughts appreciated.<span class=3D"HOEnZb">=
<font color=3D"#888888"><br><br><br></font></span></div><span class=3D"HOEn=
Zb"><font color=3D"#888888">

<p></p>

-- <br>
=A0<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 <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></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 />

--047d7b2e4edacd584c04e8ac406c--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Sun, 13 Oct 2013 22:05:02 -0700
Raw View
--001a11c1ff4419c13804e8ac6905
Content-Type: text/plain; charset=ISO-8859-1

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.

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.

I considered the possibility of permitting new-expressions and
delete-expressions during the design for N3597; the feedback I received
from other members of the committee at that time was that this was a step
too far for C++14, and I was inclined to agree.


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.


But on to your example:

On Sun, Oct 13, 2013 at 9:25 PM, Andrew Tomazos <andrewtomazos@gmail.com>wrote:

> I want this:
>
>     std::string s = "foo";
>     std::vector<int> v = {1,2,3};
>
> to be as efficient as this:
>
>     char s[] = "foo";
>     int v[] = {1,2,3};
>

All you need for this is a sufficiently talented compiler. The standard
already permits heap allocation to be promoted to stack or static storage
under N3664, and the library doesn't specify when ::operator new will be
called to provide memory for std::allocator, nor how much will be
requested, so what you're asking for is already allowed. Implementations
are getting close to being able to do these optimizations.

and I want to write this:
>
>     constexpr std::vector<int> f(...)
>     {
>         std::vector<int> v;
>
>         for (...)
>         {
>              ...
>
>              v.push_back(v);
>         }
>
>         return v;
>     }
>
> Basically, I want std::string, std::vector and similar classes to be
> literal types.
>
> The main reason they cannot currently be literal types is because they
> need to allocate objects of dynamic storage duration, and the heap isn't
> available during translation.
>
> So here are the proposed changes:
>
> - Allow new expressions and delete expressions within constexpr functions
> (provided the operands are of literal type.)
>
> - A new expression evaluated within a constexpr function in
> constant-context returns a pointer to an object of predynamic storage
> duration
>
> - A delete expression evaluated within a constexpr function in
> constant-context deletes an object of predynamic storage duration
>
> - A delete expression evaluated at run-time deletes an object of either
> predynamic or dynamic storage duration
>
> Essentially, predynamic storage duration starts during translation and can
> end as late as run-time.
>
> During translation when evaluating a new expression within a constexpr
> function the implementation allocates the object within a memory pool
> (using whatever internal system it uses to hold variables of literal type)
> we'll call the preheap.  When encountering a delete expression in a
> constexpr function it deletes the operand from the preheap.  Any predynamic
> objects left over in the preheap after translation has completed are
> arranged into the program image in a .preheap section.  When the program
> loads the .preheap section is copied into memory and serves as part of the
> initial state of the run-time heap.
>
>     constexpr int* f()
>     {
>         int a[] = {1,2,3};
>
>         int* b = new int[3];  // predynamic object allocated during
> translation
>
>         for (size_t i = 0; i < 3; i++)
>             b[i] = a[i];
>
>         return b;
>      }
>
>      constexpr int* p = f(); // f called duration translation, returns
> pointer to predynamic object
>
>      int main()
>      {
>          delete p; // deletes predynamic object at runtime
>      }
>
> Feedback/thoughts appreciated.
>
>
>  --
>
> ---
> 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/.
>

--

---
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/.

--001a11c1ff4419c13804e8ac6905
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Supporting allocate-during-translation/deallocate-during-r=
untime is pretty tricky from an implementation perspective, especially sinc=
e the usual allocation and deallocation functions can be replaced. We canno=
t know in advance what layout a custom heap will take in memory, so we cann=
ot prepopulate a &quot;preheap&quot; as a static data structure and expect =
a replacement deallocation function to be able to cope with it. (Also, prac=
tically-speaking, the compiler vendor typically does not know how the libra=
ry vendor will choose to implement the heap.) This can be mitigated by requ=
iring the implementation to repeatedly call the (replacement) ::operator ne=
w to allocate the preheap during program startup, but that removes a lot of=
 the value of the proposal.<div>
<br></div><div>More difficult is supporting types like std::vector, which w=
ant to manipulate bytes of storage, not just allocated objects. Constant ex=
pression evaluation very deliberately does not allow accessing the object r=
epresentation of a type (that is, in many cases, impossible to implement du=
ring translation, because -- for instance -- the bit pattern of types conta=
ining pointers is not yet known). A suitably careful implementation of std:=
:vector&lt;T&gt; could probably sidestep this issue, perhaps through &#39;n=
ew Uninitialized&lt;T&gt;[N];&#39;, where Uninitialized is a union type con=
taining T, but it&#39;s unlikely that any such approach would be compatible=
 with the other constraints on std::vector, such as guaranteed array-like c=
ontiguous allocation (so data()[N] works) and use of a custom allocator.</d=
iv>
<div><div><br></div><div>I considered the possibility of permitting new-exp=
ressions and delete-expressions during the design for N3597; the feedback I=
 received from other members of the committee at that time was that this wa=
s a step too far for C++14, and I was inclined to agree.<br>
</div></div><div><br></div><div><br></div><div>Having said the above, I did=
 come up with a design for this which I believe works. It&#39;s somewhat mo=
re restricted than what you were describing, but is enough to get many uses=
 of dynamic storage to work:</div>
<div><br></div><div>=A0* In order to support deleting objects in a destruct=
or, allow destructors to be marked &#39;constexpr&#39;, and implicitly mark=
 all trivial destructors as &#39;constexpr&#39;. Require a literal type to =
have a constexpr destructor rather than a trivial one.</div>
<div><br></div><div>=A0* Allow new-expressions and delete-expressions in co=
re 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 evaluatio=
n, but does not allow it to leak outside the computation. Under N3664, and =
implementation is permitted to elide this allocation rather than actually i=
nvoking the allocation/deallocation functions (and during constant expressi=
on evaluation, it would be expected to do so).</div>
<div><br></div><div>=A0* Objects declared &#39;constexpr&#39; can have non-=
trivial (but constexpr) destructors, but only if the evaluation of the dest=
ructor on the object is itself a constant expression (since the object is &=
#39;const&#39;, we can check this during translation). For such an object, =
we allow subobjects to be pointers or references to dynamic storage, so lon=
g as the evaluation of the destructor deletes the storage. Additionally, ma=
ke it undefined behavior to delete such objects outside of the destructor.<=
/div>
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><br></div><=
div class=3D"gmail_extra">But on to your example:</div><div class=3D"gmail_=
extra"><br><div class=3D"gmail_quote">On Sun, Oct 13, 2013 at 9:25 PM, Andr=
ew Tomazos <span dir=3D"ltr">&lt;<a href=3D"mailto:andrewtomazos@gmail.com"=
 target=3D"_blank">andrewtomazos@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I want this:<br><br>=A0=A0=
=A0 std::string s =3D &quot;foo&quot;;<br>=A0=A0=A0 std::vector&lt;int&gt; =
v =3D {1,2,3};<br><br>
to be as efficient as this:<br><br>=A0=A0=A0 char s[] =3D &quot;foo&quot;;<=
br>=A0=A0=A0 int v[] =3D {1,2,3};<br></div></blockquote><div><br></div><div=
>All you need for this is a sufficiently talented compiler. The standard al=
ready permits heap allocation to be promoted to stack or static storage und=
er N3664, and the library doesn&#39;t specify when ::operator new will be c=
alled to provide memory for std::allocator, nor how much will be requested,=
 so what you&#39;re asking for is already allowed. Implementations are gett=
ing close to being able to do these optimizations.</div>
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">and I want t=
o write this:<br><br>=A0=A0=A0 constexpr std::vector&lt;int&gt; f(...)<br>=
=A0=A0=A0 {<br>
=A0=A0=A0=A0=A0=A0=A0 std::vector&lt;int&gt; v;<br><br>=A0=A0=A0=A0=A0=A0=
=A0 for (...)<br>=A0=A0=A0=A0=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0 ...<br><br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 v.push_back(v);<br>=
=A0=A0=A0=A0=A0=A0=A0 }<br><br>=A0=A0=A0=A0=A0=A0=A0 return v;<br>=A0=A0=A0=
 }<br><br>Basically, I want std::string, std::vector and similar classes to=
 be literal types.<br>
<br>The main reason they cannot currently be literal types is because they =
need to allocate objects of dynamic storage duration, and the heap isn&#39;=
t available during translation.<br><br>So here are the proposed changes:<br=
>
<br>- Allow new expressions and delete expressions within constexpr functio=
ns (provided the operands are of literal type.)<br><br>- A new expression e=
valuated within a constexpr function in constant-context returns a pointer =
to an object of predynamic storage duration<br>
<br>- A delete expression evaluated within a constexpr function in constant=
-context deletes an object of predynamic storage duration<br><br>- A delete=
 expression evaluated at run-time deletes an object of either predynamic or=
 dynamic storage duration<br>
<br>Essentially, predynamic storage duration starts during translation and =
can end as late as run-time.<br><br>During translation when evaluating a ne=
w expression within a constexpr function the implementation allocates the o=
bject within a memory pool (using whatever internal system it uses to hold =
variables of literal type) we&#39;ll call the preheap.=A0 When encountering=
 a delete expression in a constexpr function it deletes the operand from th=
e preheap.=A0 Any predynamic objects left over in the preheap after transla=
tion has completed are arranged into the program image in a .preheap sectio=
n.=A0 When the program loads the .preheap section is copied into memory and=
 serves as part of the initial state of the run-time heap.<br>
<br>=A0=A0=A0 constexpr int* f()<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 in=
t a[] =3D {1,2,3};<br><br>=A0=A0=A0=A0=A0=A0=A0 int* b =3D new int[3];=A0 /=
/ predynamic object allocated during translation<br><br>=A0=A0=A0=A0=A0=A0=
=A0 for (size_t i =3D 0; i &lt; 3; i++)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 b[i] =3D a[i];<br>
<br>=A0=A0=A0=A0=A0=A0=A0 return b;<br>=A0=A0=A0=A0 }<br><br>=A0=A0=A0=A0 c=
onstexpr int* p =3D f(); // f called duration translation, returns pointer =
to predynamic object<br><br>=A0=A0=A0=A0 int main()<br>=A0=A0=A0=A0 {<br>=
=A0=A0=A0=A0=A0=A0=A0=A0 delete p; // deletes predynamic object at runtime<=
br>
=A0=A0=A0=A0 }<br><br>Feedback/thoughts appreciated.<span class=3D"HOEnZb">=
<font color=3D"#888888"><br><br><br></font></span></div><span class=3D"HOEn=
Zb"><font color=3D"#888888">

<p></p>

-- <br>
=A0<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 <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><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 />

--001a11c1ff4419c13804e8ac6905--

.


Author: David Krauss <potswa@gmail.com>
Date: Mon, 14 Oct 2013 14:23:19 +0800
Raw View
On 10/14/13 12:53 PM, Billy O'Neal wrote:
> I can't think of a real world use case where this would have a significant
> performance impact

It can't do anything for performance but shift predetermined
computations to compile time.

I think the motivation is just to promote code reuse between compile
time and runtime.

--

---
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/.

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sun, 13 Oct 2013 23:47:31 -0700 (PDT)
Raw View
------=_Part_2097_28193435.1381733251192
Content-Type: text/plain; charset=ISO-8859-1


On Monday, October 14, 2013 6:53:05 AM UTC+2, Billy O'Neal wrote:
>
> I can't think of a real world use case where this would have a significant
> performance impact, and it adds significant complexity penalties into the
> core language.
>

The main use case would be enabling the use of strings, vectors and other
types that use dynamic storage as parameters, local variables and return
types of constexpr functions.  Constexpr functions can be evaluated during
translation from within a constant expression - so enable trading one unit
of compile-time for at least n units of run-time, where n is the number of
times the program is executed, for a net benefit of at least n-1 units of
performance.

The specific use cases of using strings and vectors in functions are too
numerous to mention.  One example would be writing a character encoding
transcoder.  Such a function may take a string in the input character
encoding and return a string in the output character encoding and use a
local vector object to hold an intermediate representation:

    constexpr std::string transcode(const std::string& input)
    {
        std::vector<int> points;

        for (char c : input)
        {
             ...
             if (b)
                 points.push_back(x);
        }

        std::string output;

        for (int x : points)
        {
            if (...)
               output += ...;
        }

        return output;
    }

    constexpr std::string s = transcode("foo");

In the above transcode is called during translation and s is then
constant-initialized.  It doesn't take much creativity to think of a whole
host of other uses.
   -Andrew.


Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
>
> On Sun, Oct 13, 2013 at 9:25 PM, Andrew Tomazos <andrew...@gmail.com<javascript:>
> > wrote:
>
>> I want this:
>>
>>     std::string s = "foo";
>>     std::vector<int> v = {1,2,3};
>>
>> to be as efficient as this:
>>
>>     char s[] = "foo";
>>     int v[] = {1,2,3};
>>
>> and I want to write this:
>>
>>     constexpr std::vector<int> f(...)
>>     {
>>         std::vector<int> v;
>>
>>         for (...)
>>         {
>>              ...
>>
>>              v.push_back(v);
>>         }
>>
>>         return v;
>>     }
>>
>> Basically, I want std::string, std::vector and similar classes to be
>> literal types.
>>
>> The main reason they cannot currently be literal types is because they
>> need to allocate objects of dynamic storage duration, and the heap isn't
>> available during translation.
>>
>> So here are the proposed changes:
>>
>> - Allow new expressions and delete expressions within constexpr functions
>> (provided the operands are of literal type.)
>>
>> - A new expression evaluated within a constexpr function in
>> constant-context returns a pointer to an object of predynamic storage
>> duration
>>
>> - A delete expression evaluated within a constexpr function in
>> constant-context deletes an object of predynamic storage duration
>>
>> - A delete expression evaluated at run-time deletes an object of either
>> predynamic or dynamic storage duration
>>
>> Essentially, predynamic storage duration starts during translation and
>> can end as late as run-time.
>>
>> During translation when evaluating a new expression within a constexpr
>> function the implementation allocates the object within a memory pool
>> (using whatever internal system it uses to hold variables of literal type)
>> we'll call the preheap.  When encountering a delete expression in a
>> constexpr function it deletes the operand from the preheap.  Any predynamic
>> objects left over in the preheap after translation has completed are
>> arranged into the program image in a .preheap section.  When the program
>> loads the .preheap section is copied into memory and serves as part of the
>> initial state of the run-time heap.
>>
>>     constexpr int* f()
>>     {
>>         int a[] = {1,2,3};
>>
>>         int* b = new int[3];  // predynamic object allocated during
>> translation
>>
>>         for (size_t i = 0; i < 3; i++)
>>             b[i] = a[i];
>>
>>         return b;
>>      }
>>
>>      constexpr int* p = f(); // f called duration translation, returns
>> pointer to predynamic object
>>
>>      int main()
>>      {
>>          delete p; // deletes predynamic object at runtime
>>      }
>>
>> Feedback/thoughts appreciated.
>>
>>
>>  --
>>
>> ---
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>

--

---
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_2097_28193435.1381733251192
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>On Monday, October 14, 2013 6:53:05 AM UTC+2, Billy O'=
Neal wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px=
 solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><div d=
ir=3D"ltr">I
 can't think of a real world use case where this would have a=20
significant performance impact, and it adds significant complexity=20
penalties into the core language.</div></blockquote><br>The main use case w=
ould be enabling the use of strings, vectors and other types that use dynam=
ic storage as parameters, local variables and return types of constexpr fun=
ctions.&nbsp; Constexpr functions can be evaluated during translation from =
within a constant expression - so enable trading one unit of compile-time f=
or at least n units of run-time, where n is the number of times the program=
 is executed, for a net benefit of at least n-1 units of performance.<br><b=
r>The specific use cases of using strings and vectors in functions are too =
numerous to mention.&nbsp; One example would be writing a character encodin=
g transcoder.&nbsp; Such a function may take a string in the input characte=
r encoding and return a string in the output character encoding and use a l=
ocal vector object to hold an intermediate representation:<br><br>&nbsp;&nb=
sp;&nbsp; constexpr std::string transcode(const std::string&amp; input)<br>=
&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::vec=
tor&lt;int&gt; points;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fo=
r (char c : input)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if=
 (b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp; points.push_back(x);<br>&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=
td::string output;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=
nt x : points)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (...)<br>&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp; output +=3D ...;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><b=
r>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return output;<br>&nbsp;&nbsp;=
&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; constexpr std::string s =3D transcode("f=
oo");<br><br>In the above transcode is called during translation and s is t=
hen constant-initialized.&nbsp; It doesn't take much creativity to think of=
 a whole host of other uses.<br>&nbsp;&nbsp; -Andrew.<br><br><br clear=3D"a=
ll">

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div><div><div dir=3D"ltr"><di=
v>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" targ=
et=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"http:=
//stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://stack=
overflow.com/<wbr>users/82320/billy-oneal</a></div>

<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sun, Oct 13, 2013 at 9:25 PM, Andrew =
Tomazos <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf=
-obfuscated-mailto=3D"mCq1O9KR_RYJ">andrew...@gmail.com</a>&gt;</span> wrot=
e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">

<div dir=3D"ltr">I want this:<br><br>&nbsp;&nbsp;&nbsp; std::string s =3D "=
foo";<br>&nbsp;&nbsp;&nbsp; std::vector&lt;int&gt; v =3D {1,2,3};<br><br>to=
 be as efficient as this:<br><br>&nbsp;&nbsp;&nbsp; char s[] =3D "foo";<br>=
&nbsp;&nbsp;&nbsp; int v[] =3D {1,2,3};<br><br>

and I want to write this:<br><br>&nbsp;&nbsp;&nbsp; constexpr std::vector&l=
t;int&gt; f(...)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; std::vector&lt;int&gt; v;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; for (...)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...=
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp; v.push_back(v);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return v;<br>&nbsp;&nbsp;&nb=
sp; }<br><br>Basically, I want std::string, std::vector and similar classes=
 to be literal types.<br><br>The main reason they cannot currently be liter=
al types is because they need to allocate objects of dynamic storage durati=
on, and the heap isn't available during translation.<br>

<br>So here are the proposed changes:<br><br>- Allow new expressions and de=
lete expressions within constexpr functions (provided the operands are of l=
iteral type.)<br><br>- A new expression evaluated within a constexpr functi=
on in constant-context returns a pointer to an object of predynamic storage=
 duration<br>

<br>- A delete expression evaluated within a constexpr function in constant=
-context deletes an object of predynamic storage duration<br><br>- A delete=
 expression evaluated at run-time deletes an object of either predynamic or=
 dynamic storage duration<br>

<br>Essentially, predynamic storage duration starts during translation and =
can end as late as run-time.<br><br>During translation when evaluating a ne=
w expression within a constexpr function the implementation allocates the o=
bject within a memory pool (using whatever internal system it uses to hold =
variables of literal type) we'll call the preheap.&nbsp; When encountering =
a delete expression in a constexpr function it deletes the operand from the=
 preheap.&nbsp; Any predynamic objects left over in the preheap after trans=
lation has completed are arranged into the program image in a .preheap sect=
ion.&nbsp; When the program loads the .preheap section is copied into memor=
y and serves as part of the initial state of the run-time heap.<br>

<br>&nbsp;&nbsp;&nbsp; constexpr int* f()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int a[] =3D {1,2,3};<br><br>&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int* b =3D new int[3];&nbsp; // predynamic=
 object allocated during translation<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; for (size_t i =3D 0; i &lt; 3; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b[i] =3D a[i];<br>

<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return b;<br>&nbsp;&nbsp;&nb=
sp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp; constexpr int* p =3D f(); // f =
called duration translation, returns pointer to predynamic object<br><br>&n=
bsp;&nbsp;&nbsp;&nbsp; int main()<br>&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete p; // deletes predynamic ob=
ject at runtime<br>

&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>Feedback/thoughts appreciated.<span><font=
 color=3D"#888888"><br><br><br></font></span></div><span><font color=3D"#88=
8888">

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
mCq1O9KR_RYJ">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"mCq1O9KR_RYJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</font></span></blockquote></div><br></div>
</blockquote></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_2097_28193435.1381733251192--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Sun, 13 Oct 2013 23:50:18 -0700
Raw View
--089e01634ec2f1d81a04e8ade3c7
Content-Type: text/plain; charset=ISO-8859-1

>The main use case would be enabling the use of strings, vectors and other
types that use dynamic storage as parameters, local variables and return
types of constexpr functions

Ok, I agree that's interesting. But your proposal started out with "I want
[code sample] to be as efficient as [code sample]."

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com


On Sun, Oct 13, 2013 at 11:47 PM, Andrew Tomazos <andrewtomazos@gmail.com>wrote:

>
> On Monday, October 14, 2013 6:53:05 AM UTC+2, Billy O'Neal wrote:
>>
>> I can't think of a real world use case where this would have a
>> significant performance impact, and it adds significant complexity
>> penalties into the core language.
>>
>
> The main use case would be enabling the use of strings, vectors and other
> types that use dynamic storage as parameters, local variables and return
> types of constexpr functions.  Constexpr functions can be evaluated during
> translation from within a constant expression - so enable trading one unit
> of compile-time for at least n units of run-time, where n is the number of
> times the program is executed, for a net benefit of at least n-1 units of
> performance.
>
> The specific use cases of using strings and vectors in functions are too
> numerous to mention.  One example would be writing a character encoding
> transcoder.  Such a function may take a string in the input character
> encoding and return a string in the output character encoding and use a
> local vector object to hold an intermediate representation:
>
>     constexpr std::string transcode(const std::string& input)
>     {
>         std::vector<int> points;
>
>         for (char c : input)
>         {
>              ...
>              if (b)
>                  points.push_back(x);
>         }
>
>         std::string output;
>
>         for (int x : points)
>         {
>             if (...)
>                output += ...;
>         }
>
>         return output;
>     }
>
>     constexpr std::string s = transcode("foo");
>
> In the above transcode is called during translation and s is then
> constant-initialized.  It doesn't take much creativity to think of a whole
> host of other uses.
>    -Andrew.
>
>
> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/**users/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>> Malware Response Instructor - BleepingComputer.com
>>
>>
>> On Sun, Oct 13, 2013 at 9:25 PM, Andrew Tomazos <andrew...@gmail.com>wrote:
>>
>>>  I want this:
>>>
>>>     std::string s = "foo";
>>>     std::vector<int> v = {1,2,3};
>>>
>>> to be as efficient as this:
>>>
>>>     char s[] = "foo";
>>>     int v[] = {1,2,3};
>>>
>>> and I want to write this:
>>>
>>>     constexpr std::vector<int> f(...)
>>>     {
>>>         std::vector<int> v;
>>>
>>>         for (...)
>>>         {
>>>              ...
>>>
>>>              v.push_back(v);
>>>         }
>>>
>>>         return v;
>>>     }
>>>
>>> Basically, I want std::string, std::vector and similar classes to be
>>> literal types.
>>>
>>> The main reason they cannot currently be literal types is because they
>>> need to allocate objects of dynamic storage duration, and the heap isn't
>>> available during translation.
>>>
>>> So here are the proposed changes:
>>>
>>> - Allow new expressions and delete expressions within constexpr
>>> functions (provided the operands are of literal type.)
>>>
>>> - A new expression evaluated within a constexpr function in
>>> constant-context returns a pointer to an object of predynamic storage
>>> duration
>>>
>>> - A delete expression evaluated within a constexpr function in
>>> constant-context deletes an object of predynamic storage duration
>>>
>>> - A delete expression evaluated at run-time deletes an object of either
>>> predynamic or dynamic storage duration
>>>
>>> Essentially, predynamic storage duration starts during translation and
>>> can end as late as run-time.
>>>
>>> During translation when evaluating a new expression within a constexpr
>>> function the implementation allocates the object within a memory pool
>>> (using whatever internal system it uses to hold variables of literal type)
>>> we'll call the preheap.  When encountering a delete expression in a
>>> constexpr function it deletes the operand from the preheap.  Any predynamic
>>> objects left over in the preheap after translation has completed are
>>> arranged into the program image in a .preheap section.  When the program
>>> loads the .preheap section is copied into memory and serves as part of the
>>> initial state of the run-time heap.
>>>
>>>     constexpr int* f()
>>>     {
>>>         int a[] = {1,2,3};
>>>
>>>         int* b = new int[3];  // predynamic object allocated during
>>> translation
>>>
>>>         for (size_t i = 0; i < 3; i++)
>>>             b[i] = a[i];
>>>
>>>         return b;
>>>      }
>>>
>>>      constexpr int* p = f(); // f called duration translation, returns
>>> pointer to predynamic object
>>>
>>>      int main()
>>>      {
>>>          delete p; // deletes predynamic object at runtime
>>>      }
>>>
>>> Feedback/thoughts appreciated.
>>>
>>>
>>>  --
>>>
>>> ---
>>> 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-proposal...@**isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>>
>>> Visit this group at http://groups.google.com/a/**isocpp.org/group/std-**
>>> proposals/ <http://groups.google.com/a/isocpp.org/group/std-proposals/>.
>>>
>>
>>  --
>
> ---
> 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/.
>

--

---
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/.

--089e01634ec2f1d81a04e8ade3c7
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>&gt;The main use case would be enabling the use of st=
rings, vectors and other types that use dynamic storage as parameters, loca=
l variables and return types of constexpr functions</div><div>=A0</div><div=
>

Ok, I agree that&#39;s interesting. But your proposal started out with &quo=
t;I want [code sample] to be as efficient as [code sample].&quot;</div></di=
v><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><div>B=
illy O&#39;Neal</div>

<div><a href=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">https:=
//github.com/BillyONeal/</a></div><div><a href=3D"http://stackoverflow.com/=
users/82320/billy-oneal" target=3D"_blank">http://stackoverflow.com/users/8=
2320/billy-oneal</a></div>

<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sun, Oct 13, 2013 at 11:47 PM, Andrew=
 Tomazos <span dir=3D"ltr">&lt;<a href=3D"mailto:andrewtomazos@gmail.com" t=
arget=3D"_blank">andrewtomazos@gmail.com</a>&gt;</span> wrote:<br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex">

<div dir=3D"ltr"><div class=3D"im"><br>On Monday, October 14, 2013 6:53:05 =
AM UTC+2, Billy O&#39;Neal wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,20=
4);border-left-width:1px;border-left-style:solid">

<div dir=3D"ltr">I
 can&#39;t think of a real world use case where this would have a=20
significant performance impact, and it adds significant complexity=20
penalties into the core language.</div></blockquote><br></div>The main use =
case would be enabling the use of strings, vectors and other types that use=
 dynamic storage as parameters, local variables and return types of constex=
pr functions.=A0 Constexpr functions can be evaluated during translation fr=
om within a constant expression - so enable trading one unit of compile-tim=
e for at least n units of run-time, where n is the number of times the prog=
ram is executed, for a net benefit of at least n-1 units of performance.<br=
>

<br>The specific use cases of using strings and vectors in functions are to=
o numerous to mention.=A0 One example would be writing a character encoding=
 transcoder.=A0 Such a function may take a string in the input character en=
coding and return a string in the output character encoding and use a local=
 vector object to hold an intermediate representation:<br>

<br>=A0=A0=A0 constexpr std::string transcode(const std::string&amp; input)=
<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 std::vector&lt;int&gt; points;<br>=
<br>=A0=A0=A0=A0=A0=A0=A0 for (char c : input)<br>=A0=A0=A0=A0=A0=A0=A0 {<b=
r>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ...<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 if (b)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 points=
..push_back(x);<br>

=A0=A0=A0=A0=A0=A0=A0 }<br><br>=A0=A0=A0=A0=A0=A0=A0 std::string output;<br=
><br>=A0=A0=A0=A0=A0=A0=A0 for (int x : points)<br>=A0=A0=A0=A0=A0=A0=A0 {<=
br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (...)<br>=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 output +=3D ...;<br>=A0=A0=A0=A0=A0=A0=A0 }<br><br>=A0=
=A0=A0=A0=A0=A0=A0 return output;<br>=A0=A0=A0 }<br><br>=A0=A0=A0 constexpr=
 std::string s =3D transcode(&quot;foo&quot;);<br>

<br>In the above transcode is called during translation and s is then const=
ant-initialized.=A0 It doesn&#39;t take much creativity to think of a whole=
 host of other uses.<br>=A0=A0 -Andrew.<br><br><br clear=3D"all">

<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid"><div><div class=3D"im"><div><div dir=3D"ltr"><div>Billy O&=
#39;Neal</div>

<div><a href=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">https:=
//github.com/BillyONeal/</a></div><div><a href=3D"http://stackoverflow.com/=
users/82320/billy-oneal" target=3D"_blank">http://stackoverflow.com/<u></u>=
users/82320/billy-oneal</a></div>



<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br></div><div class=3D"gmail_quote"><div><div class=3D"h5">On Sun, Oct=
 13, 2013 at 9:25 PM, Andrew Tomazos <span dir=3D"ltr">&lt;<a>andrew...@gma=
il.com</a>&gt;</span> wrote:<br></div></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb=
(204,204,204);border-left-width:1px;border-left-style:solid">

<div><div class=3D"h5">

<div dir=3D"ltr">I want this:<br><br>=A0=A0=A0 std::string s =3D &quot;foo&=
quot;;<br>=A0=A0=A0 std::vector&lt;int&gt; v =3D {1,2,3};<br><br>to be as e=
fficient as this:<br><br>=A0=A0=A0 char s[] =3D &quot;foo&quot;;<br>=A0=A0=
=A0 int v[] =3D {1,2,3};<br><br>



and I want to write this:<br><br>=A0=A0=A0 constexpr std::vector&lt;int&gt;=
 f(...)<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 std::vector&lt;int&gt; v;<b=
r><br>=A0=A0=A0=A0=A0=A0=A0 for (...)<br>=A0=A0=A0=A0=A0=A0=A0 {<br>=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ...<br><br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 v.push_back(v);<br>


=A0=A0=A0=A0=A0=A0=A0 }<br>
<br>=A0=A0=A0=A0=A0=A0=A0 return v;<br>=A0=A0=A0 }<br><br>Basically, I want=
 std::string, std::vector and similar classes to be literal types.<br><br>T=
he main reason they cannot currently be literal types is because they need =
to allocate objects of dynamic storage duration, and the heap isn&#39;t ava=
ilable during translation.<br>



<br>So here are the proposed changes:<br><br>- Allow new expressions and de=
lete expressions within constexpr functions (provided the operands are of l=
iteral type.)<br><br>- A new expression evaluated within a constexpr functi=
on in constant-context returns a pointer to an object of predynamic storage=
 duration<br>



<br>- A delete expression evaluated within a constexpr function in constant=
-context deletes an object of predynamic storage duration<br><br>- A delete=
 expression evaluated at run-time deletes an object of either predynamic or=
 dynamic storage duration<br>



<br>Essentially, predynamic storage duration starts during translation and =
can end as late as run-time.<br><br>During translation when evaluating a ne=
w expression within a constexpr function the implementation allocates the o=
bject within a memory pool (using whatever internal system it uses to hold =
variables of literal type) we&#39;ll call the preheap.=A0 When encountering=
 a delete expression in a constexpr function it deletes the operand from th=
e preheap.=A0 Any predynamic objects left over in the preheap after transla=
tion has completed are arranged into the program image in a .preheap sectio=
n.=A0 When the program loads the .preheap section is copied into memory and=
 serves as part of the initial state of the run-time heap.<br>



<br>=A0=A0=A0 constexpr int* f()<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 in=
t a[] =3D {1,2,3};<br><br>=A0=A0=A0=A0=A0=A0=A0 int* b =3D new int[3];=A0 /=
/ predynamic object allocated during translation<br><br>=A0=A0=A0=A0=A0=A0=
=A0 for (size_t i =3D 0; i &lt; 3; i++)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 b[i] =3D a[i];<br>



<br>=A0=A0=A0=A0=A0=A0=A0 return b;<br>=A0=A0=A0=A0 }<br><br>=A0=A0=A0=A0 c=
onstexpr int* p =3D f(); // f called duration translation, returns pointer =
to predynamic object<br><br>=A0=A0=A0=A0 int main()<br>=A0=A0=A0=A0 {<br>=
=A0=A0=A0=A0=A0=A0=A0=A0 delete p; // deletes predynamic object at runtime<=
br>



=A0=A0=A0=A0 }<br><br>Feedback/thoughts appreciated.<span><font color=3D"#8=
88888"><br><br><br></font></span></div></div></div><span><font color=3D"#88=
8888"><div><div class=3D"h5">

<p></p>

-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br></div></div>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<div class=
=3D"im"><br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></font></span></blockquote></div><br></div>
</blockquote></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
=A0<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 <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></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 />

--089e01634ec2f1d81a04e8ade3c7--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 14 Oct 2013 00:00:09 -0700 (PDT)
Raw View
------=_Part_539_24092377.1381734009808
Content-Type: text/plain; charset=ISO-8859-1

On Monday, October 14, 2013 8:50:18 AM UTC+2, Billy O'Neal wrote:
>
> >The main use case would be enabling the use of strings, vectors and other
> types that use dynamic storage as parameters, local variables and return
> types of constexpr functions
>
> Ok, I agree that's interesting. But your proposal started out with "I want
> [code sample] to be as efficient as [code sample]."
>

Yeah sorry, I should have spent more time on motivations.

--

---
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_539_24092377.1381734009808
Content-Type: text/html; charset=ISO-8859-1

<div dir="ltr">On Monday, October 14, 2013 8:50:18 AM UTC+2, Billy O'Neal wrote:<blockquote style="margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote"><div dir="ltr"><div>&gt;The
 main use case would be enabling the use of strings, vectors and other
types that use dynamic storage as parameters, local variables and return
 types of constexpr functions</div><div>&nbsp;</div><div>

Ok, I agree that's interesting. But your proposal started out with "I want [code sample] to be as efficient as [code sample]."</div></div></blockquote><br clear="all">Yeah sorry, I should have spent more time on motivations.<br><br></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 email 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="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_539_24092377.1381734009808--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 14 Oct 2013 00:22:55 -0700
Raw View
On domingo, 13 de outubro de 2013 21:25:29, Andrew Tomazos wrote:
> - A new expression evaluated within a constexpr function in
> constant-context returns a pointer to an object of predynamic storage
> duration
>
> - A delete expression evaluated within a constexpr function in
> constant-context deletes an object of predynamic storage duration

Maybe what you want is a constexpr overload of operator new with a suitable ()
parameter that does a "predynamic" allocation.

That is, it doesn't allocate on the heap, but only allocates space of global
static duration. The equivalent operator delete would be a no-op.

That is

 new (std::predynamic) internal_string;

would be equivalent to having a global, unnamed static of type internal_string
and it would return its address.

We're doing this in Qt by way of lambdas:

(simplified)
#define QStringLiteral(str) []() -> QString { \
 static const QStringData p = { sizeof(str), u"" str "" }; \
 return QString(&p); \
  }

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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/.

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 14 Oct 2013 01:24:32 -0700 (PDT)
Raw View
------=_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--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 14 Oct 2013 01:45:48 -0700 (PDT)
Raw View
------=_Part_18_17363815.1381740348762
Content-Type: text/plain; charset=ISO-8859-1


Having the delete operator be a no-op creates a memory leak.  If we imagine
a vector-like class that reallocates on powers-of-2 for example being used
as a stack within a constexpr function, then it would leave a trail of
memory blocks during translation as it grows and shinks past its
thresholds.  Amusingly these blocks may be cleaned-up at link-time through
the optimizer somehow, but still the same dynamic memory management
techniques used at run-time should have the same semantics during
translation.

On Monday, October 14, 2013 9:22:55 AM UTC+2, Thiago Macieira wrote:
>
> On domingo, 13 de outubro de 2013 21:25:29, Andrew Tomazos wrote:
> > - A new expression evaluated within a constexpr function in
> > constant-context returns a pointer to an object of predynamic storage
> > duration
> >
> > - A delete expression evaluated within a constexpr function in
> > constant-context deletes an object of predynamic storage duration
>
> Maybe what you want is a constexpr overload of operator new with a
> suitable ()
> parameter that does a "predynamic" allocation.
>
> That is, it doesn't allocate on the heap, but only allocates space of
> global
> static duration. The equivalent operator delete would be a no-op.
>
> That is
>
>         new (std::predynamic) internal_string;
>
> would be equivalent to having a global, unnamed static of type
> internal_string
> and it would return its address.
>
> We're doing this in Qt by way of lambdas:
>
> (simplified)
> #define QStringLiteral(str)        []() -> QString { \
>         static const QStringData p = { sizeof(str), u"" str "" }; \
>         return QString(&p); \
>   }
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>
>

--

---
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_18_17363815.1381740348762
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>Having the delete operator be a no-op creates a memory=
 leak.&nbsp; If we imagine a vector-like class that reallocates on powers-o=
f-2 for example being used as a stack within a constexpr function, then it =
would leave a trail of memory blocks during translation as it grows and shi=
nks past its thresholds.&nbsp; Amusingly these blocks may be cleaned-up at =
link-time through the optimizer somehow, but still the same dynamic memory =
management techniques used at run-time should have the same semantics durin=
g translation.<br><br>On Monday, October 14, 2013 9:22:55 AM UTC+2, Thiago =
Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On domingo, 13 =
de outubro de 2013 21:25:29, Andrew Tomazos wrote:
<br>&gt; - A new expression evaluated within a constexpr function in=20
<br>&gt; constant-context returns a pointer to an object of predynamic stor=
age=20
<br>&gt; duration
<br>&gt;=20
<br>&gt; - A delete expression evaluated within a constexpr function in=20
<br>&gt; constant-context deletes an object of predynamic storage duration
<br>
<br>Maybe what you want is a constexpr overload of operator new with a suit=
able ()=20
<br>parameter that does a "predynamic" allocation.
<br>
<br>That is, it doesn't allocate on the heap, but only allocates space of g=
lobal=20
<br>static duration. The equivalent operator delete would be a no-op.
<br>
<br>That is
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new (std::predynamic) i=
nternal_string;
<br>
<br>would be equivalent to having a global, unnamed static of type internal=
_string=20
<br>and it would return its address.
<br>
<br>We're doing this in Qt by way of lambdas:
<br>
<br>(simplified)
<br>#define QStringLiteral(str)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;[](<wbr>) -&gt; QString { \
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static const QStringDat=
a p =3D { sizeof(str), u"" str "" }; \
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return QString(&amp;p);=
 \
<br>&nbsp; }
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" targ=
et=3D"_blank">kde.org</a>
<br>&nbsp; &nbsp;Software Architect - Intel Open Source Technology Center
<br>&nbsp; &nbsp; &nbsp; PGP/GPG: 0x6EF45358; fingerprint:
<br>&nbsp; &nbsp; &nbsp; E067 918B B660 DBD1 105C &nbsp;966C 33F5 F005 6EF4=
 5358
<br>
<br></blockquote></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_18_17363815.1381740348762--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 14 Oct 2013 08:08:21 -0700
Raw View
On segunda-feira, 14 de outubro de 2013 01:45:48, Andrew Tomazos wrote:
> Having the delete operator be a no-op creates a memory leak.  If we imagine
> a vector-like class that reallocates on powers-of-2 for example being used
> as a stack within a constexpr function, then it would leave a trail of
> memory blocks during translation as it grows and shinks past its
> thresholds.  Amusingly these blocks may be cleaned-up at link-time through
> the optimizer somehow, but still the same dynamic memory management
> techniques used at run-time should have the same semantics during
> translation.

There's no leak because the memory is static. It's freed by the program
unloading itself after exit.

When I said that it's a no-op, I meant that it doesn't do anything at runtime.
At compile time, if the compiler does detect the deletion, it might deallocate
and drop the memory area.

But it's not required to. Therefore, this may cause increased (static) memory
use if the constexpr function does alloc/dealloc multiple times. The
algorithms using this new operator new should be made so that they allocate
only once.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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/.

.


Author: Mathias Gaunard <mathias.gaunard@ens-lyon.org>
Date: Mon, 14 Oct 2013 18:36:49 +0200
Raw View
On 14/10/13 06:25, Andrew Tomazos wrote:
> I want this:
>
>      std::string s = "foo";
>      std::vector<int> v = {1,2,3};
>
> to be as efficient as this:
>
>      char s[] = "foo";
>      int v[] = {1,2,3};

The only way to make them as efficient is to use COW, which isn't
allowed for those data types.

In the first case you can change the size, in the second you cannot.
This is the real source of the overhead.

--

---
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/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 14 Oct 2013 10:34:44 -0700
Raw View
On segunda-feira, 14 de outubro de 2013 18:36:49, Mathias Gaunard wrote:
> >      std::string s = "foo";
> >      std::vector<int> v = {1,2,3};
> >
> > to be as efficient as this:
> >      char s[] = "foo";
> >      int v[] = {1,2,3};
>
> The only way to make them as efficient is to use COW, which isn't
> allowed for those data types.
>
> In the first case you can change the size, in the second you cannot.
> This is the real source of the overhead.

True, but it might be possible for a const version of those:

  constexpr std::string s = "foo long string so SSO doesn't kick in";

This requires "allocating" the internal representation of std::string
somewhere on .rodata.

That requires first that we can overload a constexpr constructor with a non-
such, and it will require the same for a constexpr destructor.

A simple implementation would do:

  string(const CharT *str) constexpr
    : _M_p(_allocdup(str))
  { }

  CharT *allocdup(const CharT *str) constexpr
  {
    auto result = static_cast<_M_Internal *>(operator new (strlen(str) +
HeaderSize, std::predynamic));
    new (result) _M_Internal(str);
    return result;
  }


--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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/.

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 14 Oct 2013 22:17:31 -0700 (PDT)
Raw View
------=_Part_2696_29442755.1381814251739
Content-Type: text/plain; charset=ISO-8859-1

On Monday, October 14, 2013 7:34:44 PM UTC+2, Thiago Macieira wrote:
>
>   string(const CharT *str) constexpr
>     : _M_p(_allocdup(str))
>   { }
>
>   CharT *allocdup(const CharT *str) constexpr
>   {
>     auto result = static_cast<_M_Internal *>(operator new (strlen(str) +
> HeaderSize, std::predynamic));
>     new (result) _M_Internal(str);
>     return result;
>   }
>

I think you're missing the consequences/properties of the proposed change.

The point is that you could write a literal type that uses dynamic memory:

    struct String
    {
        size_t len;
        char* p;

        String(const char* s)
            : len(strlen(s))
            , p(new char[len+1])
         {
               for (size_t i = 0; i < len+1; i++)
                   p[i] = s[i];
         }

         ~String()
         {
             delete [] p;
         }
    };

    constexpr String s = "foo";

    int main(int argc, char** argv)
    {
        String t = argv[0];
    }

In the above, s is constructed in constant-context, the internal new
expression returns a predynamic storage duration object allocated on the
preheap.  That object, as it isn't deleted during translation, is carried
over to run-time and becomes a normal dynamic storage duration object. This
allows the String class to be a literal type, but still use dynamic memory.

t is constructed at run-time, the internal new expression returns a dynamic
storage duration object as usual.

Notice that this is achieved with the _same_ definition of String.  Only
the underlying semantics of new and delete expressions have been extended.
The change is at a layer _below_ SSO or COW.  You can use either
optimization and it will transparently just work.

With the proposed change and some additional relaxations, standard types
such as `std::string`, `std::vector` and others could be made literal
types.  This works independantly and below how they share/manage their
internal buffers.

--

---
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_2696_29442755.1381814251739
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, October 14, 2013 7:34:44 PM UTC+2, Thiago Macie=
ira wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px =
solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">&nbsp; =
string(const CharT *str) constexpr
<br>&nbsp; &nbsp; : _M_p(_allocdup(str))
<br>&nbsp; { }
<br>
<br>&nbsp; CharT *allocdup(const CharT *str) constexpr
<br>&nbsp; {
<br>&nbsp; &nbsp; auto result =3D static_cast&lt;_M_Internal *&gt;(operator=
 new (strlen(str) +=20
<br>HeaderSize, std::predynamic));
<br>&nbsp; &nbsp; new (result) _M_Internal(str);
<br>&nbsp; &nbsp; return result;
<br>&nbsp; }
<br></blockquote><br>I think you're missing the consequences/properties of =
the proposed change.<br><br>The point is that you could write a literal typ=
e that uses dynamic memory:<br><br>&nbsp;&nbsp;&nbsp; struct String<br>&nbs=
p;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t len;<=
br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char* p;<br><br>&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String(const char* s)<br>&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : len(strlen(s))<br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , p(new char[len=
+1])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for=
 (size_t i =3D 0; i &lt; len+1; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p=
[i] =3D s[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbs=
p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~String()<br>&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete [] p;<br>&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;=
&nbsp;&nbsp; constexpr String s =3D "foo";<br><br>&nbsp;&nbsp;&nbsp; int ma=
in(int argc, char** argv)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp; String t =3D argv[0];<br>&nbsp;&nbsp;&nbsp; }<br><br>I=
n the above, s is constructed in constant-context, the internal new express=
ion returns a predynamic storage duration object allocated on the preheap.&=
nbsp; That object, as it isn't deleted during translation, is carried over =
to run-time and becomes a normal dynamic storage duration object. This allo=
ws the String class to be a literal type, but still use dynamic memory.<br>=
<br>t is constructed at run-time, the internal new expression returns a dyn=
amic storage duration object as usual.<br><br>Notice that this is achieved =
with the _same_ definition of String.&nbsp; Only the underlying semantics o=
f new and delete expressions have been extended.&nbsp; The change is at a l=
ayer _below_ SSO or COW.&nbsp; You can use either optimization and it will =
transparently just work.<br><br>With the proposed change and some additiona=
l relaxations, standard types such as `std::string`, `std::vector` and othe=
rs could be made literal types.&nbsp; This works independantly and below ho=
w they share/manage their internal buffers.<br><br></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_2696_29442755.1381814251739--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 15 Oct 2013 08:58:17 -0700
Raw View
On segunda-feira, 14 de outubro de 2013 22:17:31, Andrew Tomazos wrote:
> I think you're missing the consequences/properties of the proposed change.

I might be actually discarding it, intentionally.

> The point is that you could write a literal type that uses dynamic memory:
>
>     struct String
>     {
>         size_t len;
>         char* p;
>
>         String(const char* s)
>
>             : len(strlen(s))
>
>             , p(new char[len+1])
>          {
>                for (size_t i = 0; i < len+1; i++)
>                    p[i] = s[i];
>          }
>
>          ~String()
>          {
>              delete [] p;
>          }
>     };
>
>     constexpr String s = "foo";
>
>     int main(int argc, char** argv)
>     {
>         String t = argv[0];
>     }
>
> In the above, s is constructed in constant-context, the internal new
> expression returns a predynamic storage duration object allocated on the
> preheap.  That object, as it isn't deleted during translation, is carried
> over to run-time and becomes a normal dynamic storage duration object. This
> allows the String class to be a literal type, but still use dynamic memory.

Please, no. The object s is constexpr and the memory it allocated cannot be
deleted at runtime. The preheap is the read-only data segment of the
executable, not the normal heap.

It's quite impossible for the compiler to create a preheap in the model you're
describing, since the compiler doesn't know what malloc() or operator new()
do. The standard allows operator new() to be overridden by the user.

The only way to call the user's operator new() would be at runtime and we
already have that solution in the form of dynamic initialisation at load time.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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/.

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Tue, 15 Oct 2013 11:23:24 -0700 (PDT)
Raw View
------=_Part_302_13528474.1381861404171
Content-Type: text/plain; charset=ISO-8859-1

On Tuesday, October 15, 2013 5:58:17 PM UTC+2, Thiago Macieira wrote:
>
> Please, no. The object s is constexpr and the memory it allocated cannot
> be
> deleted at runtime. The preheap is the read-only data segment of the
> executable, not the normal heap.
>

That is not what I proposed, no.  Objects allocated (and not yet deleted)
on the preheap during translation are saved in the program and logically
become part of the heap at run-time.  That is the point, and what makes it
useful - because you can effectively use new/delete in literal types.
Literal types can be used freely both during translation and at run-time
with a single reusable type definition.

It's quite impossible for the compiler to create a preheap in the model
> you're
>
describing, since the compiler doesn't know what malloc() or operator new()
> do. The standard allows operator new() to be overridden by the user.
>

No, it is possible.  Preheap objects are represented during translation in
the same way as literal temporaries, local variables in constexpr functions
and constexpr objects of static storage duration.  At load-time preheap
objects are automatically loaded into the heap.  As Richard suggests
implementations can allocate run-time storage for preheap objects at
load-time using the allocation functions at that time (overridden or not) -
although they would be free to elide the "copying" you are imagining in
favor of more efficient ways given sufficient integration/intelligence of
the different components of the implementation.  But _with or without_ such
load-time copying, it is still enormously useful.  I wouldn't get too hung
up on the particular mechanism and overlook the larger utility.


> The only way to call the user's operator new() would be at runtime and we
> already have that solution in the form of dynamic initialisation at load
> time.
>

You're confusing the value of an object, with the storage/representation
for that object.  In particular just because a preheap object is already
logically constructed during translation, doesn't mean we can't use a
custom allocation function to get the run-time storage for it later at
load-time.  Note that the utility of preheap objects extends way beyond
what can be achieved with dynamic initialization.  In particular they can
be used during translaiton within literal types _before_ dynamic
initialization takes place at run-time.  Admittedly my opening example did
not do a good job of demonstrating this, but it is a clear consequence of
the proposed change.

--

---
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_302_13528474.1381861404171
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, October 15, 2013 5:58:17 PM UTC+2, Thiago Maci=
eira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Please, no. The obj=
ect s is constexpr and the memory it allocated cannot be=20
<br>deleted at runtime. The preheap is the read-only data segment of the=20
<br>executable, not the normal heap.
<br></blockquote><div><br>That is not what I proposed, no.&nbsp; Objects al=
located (and not yet deleted) on the preheap during translation are saved i=
n the program and logically become part of the heap at run-time.&nbsp; That=
 is the point, and what makes it useful - because you can effectively use n=
ew/delete in literal types.&nbsp; Literal types can be used freely both dur=
ing translation and at run-time with a single reusable type definition.<br>=
<br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid =
rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">It's quite im=
possible for the compiler to create a preheap in the model you're=20
<br></blockquote></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">describ=
ing, since the compiler doesn't know what malloc() or operator new()=20
<br>do. The standard allows operator new() to be overridden by the user.
<br></blockquote><div><br>No, it is possible.&nbsp; Preheap objects are rep=
resented during translation in the same way as literal temporaries, local v=
ariables in constexpr functions and constexpr objects of static storage dur=
ation.&nbsp; At load-time preheap objects are automatically loaded into the=
 heap.&nbsp; As Richard suggests implementations can allocate run-time stor=
age for preheap objects at load-time using the allocation functions at that=
 time (overridden or not) - although they would be free to elide the "copyi=
ng" you are imagining in favor of more efficient ways given sufficient inte=
gration/intelligence of the different components of the implementation.&nbs=
p; But _with or without_ such load-time copying, it is still enormously use=
ful.&nbsp; I wouldn't get too hung up on the particular mechanism and overl=
ook the larger utility.<br>&nbsp;<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">The only way to call the user's operator new() would be at run=
time and we=20
<br>already have that solution in the form of dynamic initialisation at loa=
d time.
<br></blockquote><div>&nbsp;<br>You're confusing the value of an object, wi=
th the storage/representation for that object.&nbsp; In particular just bec=
ause a preheap object is already logically constructed during translation, =
doesn't mean we can't use a custom allocation function to get the run-time =
storage for it later at load-time.&nbsp; Note that the utility of preheap o=
bjects extends way beyond what can be achieved with dynamic initialization.=
&nbsp; In particular they can be used during translaiton within literal typ=
es _before_ dynamic initialization takes place at run-time.&nbsp; Admittedl=
y my opening example did not do a good job of demonstrating this, but it is=
 a clear consequence of the proposed change.<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_302_13528474.1381861404171--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Tue, 15 Oct 2013 21:18:20 +0200
Raw View
On Tue, 2013-10-15 at 11:23 -0700, Andrew Tomazos wrote:
> On Tuesday, October 15, 2013 5:58:17 PM UTC+2, Thiago Macieira wrote:
>         Please, no. The object s is constexpr and the memory it
>         allocated cannot be
>         deleted at runtime. The preheap is the read-only data segment
>         of the
>         executable, not the normal heap.
>
> That is not what I proposed, no.  Objects allocated (and not yet
> deleted) on the preheap during translation are saved in the program
> and logically become part of the heap at run-time.  That is the point,
> and what makes it useful - because you can effectively use new/delete
> in literal types.  Literal types can be used freely both during
> translation and at run-time with a single reusable type definition.
>
>         It's quite impossible for the compiler to create a preheap in
>         the model you're
>         describing, since the compiler doesn't know what malloc() or
>         operator new()
>         do. The standard allows operator new() to be overridden by the
>         user.
>
> No, it is possible.  Preheap objects are represented during
> translation in the same way as literal temporaries, local variables in
> constexpr functions and constexpr objects of static storage duration.
> At load-time preheap objects are automatically loaded into the heap.
> As Richard suggests implementations can allocate run-time storage for
> preheap objects at load-time using the allocation functions at that
> time (overridden or not) - although they would be free to elide the
> "copying" you are imagining in favor of more efficient ways given
> sufficient integration/intelligence of the different components of the
> implementation.  But _with or without_ such load-time copying, it is
> still enormously useful.  I wouldn't get too hung up on the particular
> mechanism and overlook the larger utility.
>
>
>         The only way to call the user's operator new() would be at
>         runtime and we
>         already have that solution in the form of dynamic
>         initialisation at load time.
>
> You're confusing the value of an object, with the
> storage/representation for that object.  In particular just because a
> preheap object is already logically constructed during translation,
> doesn't mean we can't use a custom allocation function to get the
> run-time storage for it later at load-time.  Note that the utility of
> preheap objects extends way beyond what can be achieved with dynamic
> initialization.  In particular they can be used during translaiton
> within literal types _before_ dynamic initialization takes place at
> run-time.  Admittedly my opening example did not do a good job of
> demonstrating this, but it is a clear consequence of the proposed
> change.

But what prevents a sufficiently advanced compiler from doing this using
C++11 (or for that sake, C++98)?

This sounds like the as-if rule being applied to object initializations.

/MF


--

---
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/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 15 Oct 2013 14:09:24 -0700
Raw View
On ter=E7a-feira, 15 de outubro de 2013 21:18:20, Magnus Fromreide wrote:
> But what prevents a sufficiently advanced compiler from doing this using
> C++11 (or for that sake, C++98)?

I don't think it can do that. The compiler does not know what other side=20
effects operator new() might have. It violates the requirements for constex=
pr.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 15 Oct 2013 14:39:17 -0700
Raw View
On ter=E7a-feira, 15 de outubro de 2013 11:23:24, Andrew Tomazos wrote:
> On Tuesday, October 15, 2013 5:58:17 PM UTC+2, Thiago Macieira wrote:
> > Please, no. The object s is constexpr and the memory it allocated canno=
t
> > be
> > deleted at runtime. The preheap is the read-only data segment of the
> > executable, not the normal heap.
>=20
> That is not what I proposed, no.

I know.

>>  It's quite impossible for the compiler to create a preheap in the model
>> you're
>> describing, since the compiler doesn't know what malloc() or operator ne=
w()
>> do. The standard allows operator new() to be overridden by the user.
>=20
> No, it is possible.  Preheap objects are represented during translation i=
n
> the same way as literal temporaries, local variables in constexpr functio=
ns
> and constexpr objects of static storage duration.  At load-time preheap
> objects are automatically loaded into the heap.  As Richard suggests
> implementations can allocate run-time storage for preheap objects at
> load-time using the allocation functions at that time (overridden or not)=
 -
> although they would be free to elide the "copying" you are imagining in
> favor of more efficient ways given sufficient integration/intelligence of
> the different components of the implementation.  But _with or without_ su=
ch
> load-time copying, it is still enormously useful.  I wouldn't get too hun=
g
> up on the particular mechanism and overlook the larger utility.

It might be useful if you describe what you expect to happen during=20
compilation, during load time, during runtime, and during unload time. The =
way=20
I am currently seeing things, you're asking for a lot in the compiler for v=
ery=20
little benefit: since the allocation must be redone at load-time, there's n=
o=20
gain.

Let's take your simple but not trivial constructor from a few emails back:

        String(const char* s)
            : len(strlen(s))
            , p(new char[len+1])
         {
               for (size_t i =3D 0; i < len+1; i++)
                   p[i] =3D s[i];
         }

And we have the following global declaration:
 constexpr String mystring("Hello");

During compilation, what will the compiler do? The first thing it needs to =
do=20
is call strlen("Hello"). Let's assume that it is constexpr, so the compiler=
=20
can know that it will return 5.=20

Now we have a call to ::operator new(6). What will the compiler do?

I'm going to assume the compiler allocates a "preheap" -- that is, some sta=
tic=20
storage of length 6. The compiler knows the return value since it allocated=
=20
the address. After that, it will execute the loop.

At the end of the function, it could conclude that the memory layout should=
 be=20
(pseudo-assembly):

 .section .rodata, read-only, sharable
 Lalloc_size_6:
  .asciz "Hello"
 mystring:
  .quad 5
  .quad Lalloc_size_6

If nothing happened at load time, we would have a perfectly valid String=20
object, with len =3D=3D 5 and p pointing to a read-only section of memory.=
=20
Obviously, you can't delete p. This is already enormously useful for QStrin=
g,=20
which uses copy-on-write semantics. All we need is a flag indicating that t=
his=20
string is immutable, which QString has.

std::string has no such semantic, true. But all it requires to support an=
=20
immutable string data is a special allocator template, which causes the=20
destructor to be empty and the move constructor to be equal to the copy=20
constructor. Since the object is already const, no mutator functions can be=
=20
called, so no reallocation will ever happen.

Now, you said "At load-time preheap objects are automatically loaded into t=
he=20
heap." That means the compiler must emit load- and unload-time functions li=
ke:

 void init()
 {
  decltype(mystring.p) tmp =3D new char[6];
  std::memcpy(tmp, mystring.p, 6);
  mystring.p =3D tmp;
 }
 void fini()
 {
  delete[] mystring.p;
 }

The second consequence is that the "mystring" object cannot be placed in a=
=20
read-only & sharable section of memory, since we needed to modify mystring.=
p.=20
The compiler needs to place this constexpr object in a read-write section o=
f=20
memory. At best, with the help from the program loader, the memory page can=
 be=20
set to read-only after initialisation (similar to the GNU -z relro solution=
).

Here's my question: what's the benefit? If we replace that constexpr with a=
=20
simple const keyword, current C++98 code would generate the following load-=
=20
and unload-time functions (after inlining the constructor and destructor):

 void init()
 {
  mystring.len =3D 5;
  decltype(mystring.p) tmp =3D new char[6];
  std::memcpy(tmp, "Hello", 6);
  mystring.p =3D tmp;
 }
 void fini()
 {
  delete[] mystring.p;
 }

The difference is the assignment of mystring.len. That's hardly worth the=
=20
effort, IMHO.

> > The only way to call the user's operator new() would be at runtime and =
we
> > already have that solution in the form of dynamic initialisation at loa=
d
> > time.
>=20
> You're confusing the value of an object, with the storage/representation
> for that object.  In particular just because a preheap object is already
> logically constructed during translation, doesn't mean we can't use a
> custom allocation function to get the run-time storage for it later at
> load-time.  Note that the utility of preheap objects extends way beyond
> what can be achieved with dynamic initialization.  In particular they can
> be used during translaiton within literal types _before_ dynamic
> initialization takes place at run-time.  Admittedly my opening example di=
d
> not do a good job of demonstrating this, but it is a clear consequence of
> the proposed change.

I'm not questioning the usefulness of having new in constexpr. They'd come =
in=20
extremely handy.

I'm questioning the need to reload preheap objects into the real heap. That=
=20
kills most of the benefit of the functionality.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Wed, 16 Oct 2013 00:10:54 -0700 (PDT)
Raw View
------=_Part_1124_10834884.1381907454890
Content-Type: text/plain; charset=ISO-8859-1

On Tuesday, October 15, 2013 11:39:17 PM UTC+2, Thiago Macieira wrote:
>
> >>  It's quite impossible for the compiler to create a preheap in the
> model
> >> you're
> >> describing, since the compiler doesn't know what malloc() or operator
> new()
> >> do. The standard allows operator new() to be overridden by the user.
> >
> > No, it is possible.  Preheap objects are represented during translation
> in
> > the same way as literal temporaries, local variables in constexpr
> functions
> > and constexpr objects of static storage duration.  At load-time preheap
> > objects are automatically loaded into the heap.  As Richard suggests
> > implementations can allocate run-time storage for preheap objects at
> > load-time using the allocation functions at that time (overridden or
> not) -
> > although they would be free to elide the "copying" you are imagining in
> > favor of more efficient ways given sufficient integration/intelligence
> of
> > the different components of the implementation.  But _with or without_
> such
> > load-time copying, it is still enormously useful.  I wouldn't get too
> hung
> > up on the particular mechanism and overlook the larger utility.
>
> It might be useful if you describe what you expect to happen during
> compilation, during load time, during runtime, and during unload time. The
> way
> I am currently seeing things, you're asking for a lot in the compiler for
> very
> little benefit: since the allocation must be redone at load-time, there's
> no
> gain.
>

No, the run-time storage allocation is not redone at load-time, it is done
for the first time at load-time.


> Let's take your simple but not trivial constructor from a few emails back:
>
>         String(const char* s)
>             : len(strlen(s))
>             , p(new char[len+1])
>          {
>                for (size_t i = 0; i < len+1; i++)
>                    p[i] = s[i];
>          }
>
> And we have the following global declaration:
>         constexpr String mystring("Hello");
>
> During compilation, what will the compiler do? The first thing it needs to
> do
> is call strlen("Hello"). Let's assume that it is constexpr, so the
> compiler
> can know that it will return 5.
>
> Now we have a call to ::operator new(6). What will the compiler do?
>

No, that is not how it works.  `new char[6]` creates a literal preheap
object of type array of 6 char.  It does not call new(bytes).  This is the
same as what happens in the following currently:

    typedef char A[6];

    constexpr char e = A{'H' , 'e', 'l', 'l', 'o', '\0'}[1];

In the above the compiler creates a temporary during translation of type
array of 6 char.  It can do this because that type is a literal type. It
does not allocate storage nor does it know the run-time representation
(specific bit pattern).  The literal type is represented within the
implementations compile-time system symbolically.  The preheap at
compile-time is simply a collection of such literal temporaries with their
values represented symbolically.

I'm going to assume the compiler allocates a "preheap" -- that is, some
> static
> storage of length 6. The compiler knows the return value since it
> allocated
> the address. After that, it will execute the loop.
>

No, it does not know the specific address.  This is the same as:

     int x;
     constexpr int* p = &x;

During translation p is represented symbolically.  It doesn't have the
final address until load-time.  p can still be used in a constant
expression because the rules are setup to support this symbolic literal
representation.  It cannot however, for example, undergo a reinterpet_cast
to an integer, specifically for this reason (it doesn't have the bits yet).


> At the end of the function, it could conclude that the memory layout
> should be
> (pseudo-assembly):
>
>         .section .rodata, read-only, sharable
>         Lalloc_size_6:
>                 .asciz        "Hello"
>         mystring:
>                 .quad        5
>                 .quad        Lalloc_size_6
>

No, not what I am proposing.  You are focusing on the mechanism and not the
logical behaviour.  As one way of implementing the mechanism: a new section
separate from .rodata could be created to hold preheap objects called
..preheap.  At load-time the implementation loads that section read-only
into memory, calls new(bytes) for each preheap object, copies some bits
from the .preheap section to the newly allocated run-time storage, then
based on the returned pointers relocates pointers to preheap objects, then
_unloads_ the .preheap section (alternatively it will just page out back to
the program image because the .preheap section will never be read again,
but that is an implementation detail).  The .preheap section doesn't need
to occupy resources during run-time, it is released after loading.  But
again, that is all just mechanism, and overlooks the utility.

Notice how the preheap objects are created and used during translation, the
run-time storage is allocated at load-time, and they can then continue to
be used at run-time and then deleted during run-time.  That is the point.
So you can write code that uses new and delete, and it will work the same
during translation or at run-time.


> If nothing happened at load time, we would have a perfectly valid String
> object, with len == 5 and p pointing to a read-only section of memory.
> Obviously, you can't delete p. This is already enormously useful for
> QString,
> which uses copy-on-write semantics. All we need is a flag indicating that
> this
> string is immutable, which QString has.
>

You're talking about something different now.  Literal types are not
necessarily immutable, as for example literal temporaries and local
variables in constexpr functions are not.  Also a dynamic object must be
able to be deleted during run-time in order to release its resources.
Objects of static storage duration do not have this property.

std::string has no such semantic, true. But all it requires to support an
> immutable string data is a special allocator template, which causes the
> destructor to be empty and the move constructor to be equal to the copy
> constructor. Since the object is already const, no mutator functions can
> be
> called, so no reallocation will ever happen.
>

Again, you are talking about something different now.  How to design a
string class with respect to immutability.  It is separate from preheap
objects, and overlooks the utility.


> Now, you said "At load-time preheap objects are automatically loaded into
> the
> heap." That means the compiler must emit load- and unload-time functions
> like:
>
>         void init()
>         {
>                 decltype(mystring.p) tmp = new char[6];
>                 std::memcpy(tmp, mystring.p, 6);
>                 mystring.p = tmp;
>         }
>         void fini()
>         {
>                 delete[] mystring.p;
>         }
>
> The second consequence is that the "mystring" object cannot be placed in a
> read-only & sharable section of memory, since we needed to modify
> mystring.p.
> The compiler needs to place this constexpr object in a read-write section
> of
> memory. At best, with the help from the program loader, the memory page
> can be
> set to read-only after initialisation (similar to the GNU -z relro
> solution).
>

No, in my example the array of char is not defined with constexpr.  Preheap
objects can be mutated at both compile-time and run-time.  They only have
to be literal so they can be used at compile-time.

Here's my question: what's the benefit? If we replace that constexpr with a
> simple const keyword, current C++98 code would generate the following
> load-
> and unload-time functions (after inlining the constructor and destructor):
>

I'm questioning the need to reload preheap objects into the real heap. That
> kills most of the benefit of the functionality.
>

No, it doesn't.  You're confusing immutability of strings with the utility
of what is proposed.

I agree I need to write a more elaborate demo to show off the full utility
of what I propose.  Clearly you are not seeing it yet.
  -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_1124_10834884.1381907454890
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, October 15, 2013 11:39:17 PM UTC+2, Thiago Mac=
ieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt;&gt; &nbsp;It'=
s quite impossible for the compiler to create a preheap in the model
<br>&gt;&gt; you're
<br>&gt;&gt; describing, since the compiler doesn't know what malloc() or o=
perator new()
<br>&gt;&gt; do. The standard allows operator new() to be overridden by the=
 user.
<br>&gt;=20
<br>&gt; No, it is possible. &nbsp;Preheap objects are represented during t=
ranslation in
<br>&gt; the same way as literal temporaries, local variables in constexpr =
functions
<br>&gt; and constexpr objects of static storage duration. &nbsp;At load-ti=
me preheap
<br>&gt; objects are automatically loaded into the heap. &nbsp;As Richard s=
uggests
<br>&gt; implementations can allocate run-time storage for preheap objects =
at
<br>&gt; load-time using the allocation functions at that time (overridden =
or not) -
<br>&gt; although they would be free to elide the "copying" you are imagini=
ng in
<br>&gt; favor of more efficient ways given sufficient integration/intellig=
ence of
<br>&gt; the different components of the implementation. &nbsp;But _with or=
 without_ such
<br>&gt; load-time copying, it is still enormously useful. &nbsp;I wouldn't=
 get too hung
<br>&gt; up on the particular mechanism and overlook the larger utility.
<br>
<br>It might be useful if you describe what you expect to happen during=20
<br>compilation, during load time, during runtime, and during unload time. =
The way=20
<br>I am currently seeing things, you're asking for a lot in the compiler f=
or very=20
<br>little benefit: since the allocation must be redone at load-time, there=
's no=20
<br>gain.
<br></blockquote><div><br>No, the run-time storage allocation is not redone=
 at load-time, it is done for the first time at load-time.<br>&nbsp;</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">Let's take your simple but not =
trivial constructor from a few emails back:
<br>
<br>&nbsp; &nbsp; &nbsp; &nbsp; String(const char* s)
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : len(strlen(s))
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , p(new char[len+1])
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for (size_t i =
=3D 0; i &lt; len+1; i++)
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p[=
i] =3D s[i];
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
<br>
<br>And we have the following global declaration:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constexpr String mystri=
ng("Hello");
<br>
<br>During compilation, what will the compiler do? The first thing it needs=
 to do=20
<br>is call strlen("Hello"). Let's assume that it is constexpr, so the comp=
iler=20
<br>can know that it will return 5.=20
<br>
<br>Now we have a call to ::operator new(6). What will the compiler do?
<br></blockquote><div>&nbsp;<br>No, that is not how it works.&nbsp; `new ch=
ar[6]` creates a literal preheap object of type array of 6 char.&nbsp; It d=
oes not call new(bytes).&nbsp; This is the same as what happens in the foll=
owing currently:<br><br>&nbsp;&nbsp;&nbsp; typedef char A[6];<br><br>&nbsp;=
&nbsp;&nbsp; constexpr char e =3D A{'H' , 'e', 'l', 'l', 'o', '\0'}[1];<br>=
<br>In the above the compiler creates a temporary during translation of typ=
e array of 6 char.&nbsp; It can do this because that type is a literal type=
.. It does not allocate storage nor does it know the run-time representation=
 (specific bit pattern).&nbsp; The literal type is represented within the i=
mplementations compile-time system symbolically.&nbsp; The preheap at compi=
le-time is simply a collection of such literal temporaries with their value=
s represented symbolically.<br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">I'm going to assume the compiler allocates a "preheap" -- that i=
s, some static=20
<br>storage of length 6. The compiler knows the return value since it alloc=
ated=20
<br>the address. After that, it will execute the loop.
<br></blockquote><div><br>No, it does not know the specific address.&nbsp; =
This is the same as:<br><br>&nbsp; &nbsp;&nbsp; int x;<br>&nbsp; &nbsp;&nbs=
p; constexpr int* p =3D &amp;x;<br><br>During translation p is represented =
symbolically.&nbsp; It doesn't have the final address until load-time.&nbsp=
; p can still be used in a constant expression because the rules are setup =
to support this symbolic literal representation.&nbsp; It cannot however, f=
or example, undergo a reinterpet_cast to an integer, specifically for this =
reason (it doesn't have the bits yet).<br></div><div>&nbsp;</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">At the end of the function, it could con=
clude that the memory layout should be=20
<br>(pseudo-assembly):
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.section .rodata, read-=
only, sharable
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lalloc_size_6:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;.asciz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;<wbr>"Hello"
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mystring:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;.quad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;5
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;.quad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;<wbr>Lalloc_size_6
<br></blockquote><div><br>No, not what I am proposing.&nbsp; You are focusi=
ng on the mechanism and not the logical behaviour.&nbsp; As one way of impl=
ementing the mechanism: a new section separate from .rodata could be create=
d to hold preheap objects called .preheap.&nbsp; At load-time the implement=
ation loads that section read-only into memory, calls new(bytes) for each p=
reheap object, copies some bits from the .preheap section to the newly allo=
cated run-time storage, then based on the returned pointers relocates point=
ers to preheap objects, then _unloads_ the .preheap section (alternatively =
it will just page out back to the program image because the .preheap sectio=
n will never be read again, but that is an implementation detail).&nbsp; Th=
e .preheap section doesn't need to occupy resources during run-time, it is =
released after loading.&nbsp; But again, that is all just mechanism, and ov=
erlooks the utility.<br><br>Notice how the preheap objects are created and =
used during translation, the run-time storage is allocated at load-time, an=
d they can then continue to be used at run-time and then deleted during run=
-time.&nbsp; That is the point.&nbsp; So you can write code that uses new a=
nd delete, and it will work the same during translation or at run-time.<br>=
&nbsp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">If nothing hap=
pened at load time, we would have a perfectly valid String=20
<br>object, with len =3D=3D 5 and p pointing to a read-only section of memo=
ry.=20
<br>Obviously, you can't delete p. This is already enormously useful for QS=
tring,=20
<br>which uses copy-on-write semantics. All we need is a flag indicating th=
at this=20
<br>string is immutable, which QString has.
<br></blockquote><div><br>You're talking about something different now.&nbs=
p; Literal types are not necessarily immutable, as for example literal temp=
oraries and local variables in constexpr functions are not.&nbsp; Also a dy=
namic object must be able to be deleted during run-time in order to release=
 its resources.&nbsp; Objects of static storage duration do not have this p=
roperty.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">std::str=
ing has no such semantic, true. But all it requires to support an=20
<br>immutable string data is a special allocator template, which causes the=
=20
<br>destructor to be empty and the move constructor to be equal to the copy=
=20
<br>constructor. Since the object is already const, no mutator functions ca=
n be=20
<br>called, so no reallocation will ever happen.
<br></blockquote><div><br>Again, you are talking about something different =
now.&nbsp; How to design a string class with respect to immutability.&nbsp;=
 It is separate from preheap objects, and overlooks the utility.<br></div><=
div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Now, you said =
"At load-time preheap objects are automatically loaded into the=20
<br>heap." That means the compiler must emit load- and unload-time function=
s like:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void init()
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;decltype(<wbr>mystring.p) tmp =3D new char[6];
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;std::memcpy(<wbr>tmp, mystring.p, 6);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;mystring.p =3D tmp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fini()
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;delete[] mystring.p;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
<br>
<br>The second consequence is that the "mystring" object cannot be placed i=
n a=20
<br>read-only &amp; sharable section of memory, since we needed to modify m=
ystring.p.=20
<br>The compiler needs to place this constexpr object in a read-write secti=
on of=20
<br>memory. At best, with the help from the program loader, the memory page=
 can be=20
<br>set to read-only after initialisation (similar to the GNU -z relro solu=
tion).
<br></blockquote><div>&nbsp;<br>No, in my example the array of char is not =
defined with constexpr.&nbsp; Preheap objects can be mutated at both compil=
e-time and run-time.&nbsp; They only have to be literal so they can be used=
 at compile-time.<br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
>Here's my question: what's the benefit? If we replace that constexpr with =
a=20
<br>simple const keyword, current C++98 code would generate the following l=
oad-=20
<br>and unload-time functions (after inlining the constructor and destructo=
r):
<br></blockquote><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">I'm quest=
ioning the need to reload preheap objects into the real heap. That=20
<br>kills most of the benefit of the functionality.
<br></blockquote><div><br>No, it doesn't.&nbsp; You're confusing immutabili=
ty of strings with the utility of what is proposed.<br><br>I agree I need t=
o write a more elaborate demo to show off the full utility of what I propos=
e.&nbsp; Clearly you are not seeing it yet.<br>&nbsp; -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_1124_10834884.1381907454890--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 16 Oct 2013 08:41:02 -0700
Raw View
--nextPart10984865.v4tTNLzchV
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On quarta-feira, 16 de outubro de 2013 00:10:54, Andrew Tomazos wrote:
> I agree I need to write a more elaborate demo to show off the full utility
> of what I propose.  Clearly you are not seeing it yet.

Indeed, I'm not.

You've said "no" to almost everything I said, but then followed up by
explaining exactly the same that I had already explained, just with different
words or by changing something that represents no net effect (for example, it
doesn't matter that the "Hello\0" is in .rodata or .preheap; something needs
to know its address and allocate memory for it).

Again, I'm not questioning the benefit of the feature of using operator new()
in constexpr. I am questioning the "reallocate preheap into real heap at load-
time".

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--nextPart10984865.v4tTNLzchV
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBSXrOVM/XwBW70U1gRAqeWAJ48bHJUgJRrvT/3cG0MN+l5rk7dcwCfaTsB
z+AWa3IU5cFS84zP704K+ow=
=qJjt
-----END PGP SIGNATURE-----

--nextPart10984865.v4tTNLzchV--


.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 16 Oct 2013 10:46:09 -0500
Raw View
--001a11c2e39007d98b04e8dd9cfd
Content-Type: text/plain; charset=ISO-8859-1

On 16 October 2013 02:10, Andrew Tomazos <andrewtomazos@gmail.com> wrote:

>
> No, not what I am proposing.  You are focusing on the mechanism and not
> the logical behaviour.


Because you are trying to shoehorn this into existing types where there is
behavior you care about and behavior you don't.  We have to make sure that
the behavior you don't care about isn't observable behavior according to
the standard.

If this were a proposal for basic_string<char, char_traits<char>,
magic_allocator<char>>, a lot of the problem goes away, but so does the
interoperability.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.

--001a11c2e39007d98b04e8dd9cfd
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra">On 16 October 2013 02:10, Andre=
w Tomazos <span dir=3D"ltr">&lt;<a href=3D"mailto:andrewtomazos@gmail.com" =
target=3D"_blank">andrewtomazos@gmail.com</a>&gt;</span> wrote:<br><div cla=
ss=3D"gmail_quote">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br>No, not what I am proposing.=A0 You are =
focusing on the mechanism and not the logical behaviour.</blockquote></div>=
<br>

</div><div class=3D"gmail_extra">Because you are trying to shoehorn this in=
to existing types where there is behavior you care about and behavior you d=
on&#39;t.=A0 We have to make sure that the behavior you don&#39;t care abou=
t isn&#39;t observable behavior according to the standard.<br>

</div><div class=3D"gmail_extra"><br clear=3D"all"></div><div class=3D"gmai=
l_extra">If this were a proposal for basic_string&lt;char, char_traits&lt;c=
har&gt;, magic_allocator&lt;char&gt;&gt;, a lot of the problem goes away, b=
ut so does the interoperability.<br>

</div><div class=3D"gmail_extra">-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &=
lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin=
@eviloverlord.com</a>&gt;=A0 (847) 691-1404
</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 />

--001a11c2e39007d98b04e8dd9cfd--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Wed, 16 Oct 2013 22:39:12 -0700 (PDT)
Raw View
------=_Part_278_24444519.1381988352568
Content-Type: text/plain; charset=ISO-8859-1

On Wednesday, October 16, 2013 5:41:02 PM UTC+2, Thiago Macieira wrote:
>
> it doesn't matter that the "Hello\0" is in .rodata or .preheap; something
> needs
> to know its address and allocate memory for it.
>

..rodata needs to be accessible for the lifetime of the program, the
..preheap section can be unloaded immediately after loading has completed,
reclaiming its resources.  (If you mix them together it will lock the pages
in memory.)  The concern is about resource management.  If we didn't care
about resource usage then making the current normal delete a no-op would
still result in a correct program, it would just use extra memory over its
lifetime, making the heap into a memory pool.

Again, I'm not questioning the benefit of the feature of using operator
> new()
> in constexpr. I am questioning the "reallocate preheap into real heap at
> load-
> time".
>

Such an architecture would use less resources.  Placing preheap objects in
the heap allows them to be deleted during run-time, reclaiming their
resources.  If we placed them in .rodata they could not be deleted.

Consider the following program:

    typedef int T;

    constexpr T* p = new T(3);

    static_assert(*p == 3);

    int main()
    {
        /* loader() */
        first_half();
        delete p;
        second_half();
    }

In the above, for the duration of second_half() the resources used to back
the predynamic object are available for use.  This is achieved because
preheap objects are loaded into the heap.  Note the .preheap section is
unloaded by the end of `loader()`.

If we allocated it as a static storage duration object as you suggest, the
resources would still be occupied for second_half().

--

---
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_278_24444519.1381988352568
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, October 16, 2013 5:41:02 PM UTC+2, Thiago Ma=
cieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">it=20
doesn't matter that the "Hello\0" is in .rodata or .preheap; something need=
s=20
<br>to know its address and allocate memory for it.
<br></blockquote><div>&nbsp;<br>.rodata needs to be accessible for the life=
time of the program, the .preheap section can be unloaded immediately after=
 loading has completed, reclaiming its resources.&nbsp; (If you mix them to=
gether it will lock the pages in memory.)&nbsp; The concern is about resour=
ce management.&nbsp; If we didn't care about resource usage then making the=
 current normal delete a no-op would still result in a correct program, it =
would just use extra memory over its lifetime, making the heap into a memor=
y pool.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Again, I'=
m not questioning the benefit of the feature of using operator new()=20
<br>in constexpr. I am questioning the "reallocate preheap into real heap a=
t load-
<br>time".
<br></blockquote><div><br>Such an architecture would use less resources.&nb=
sp; Placing preheap objects in the heap allows them to be deleted during ru=
n-time, reclaiming their resources.&nbsp; If we placed them in .rodata they=
 could not be deleted.<br><br>Consider the following program:<br><br>&nbsp;=
&nbsp;&nbsp; typedef int T;<br><br>&nbsp;&nbsp;&nbsp; constexpr T* p =3D ne=
w T(3);<br><br>&nbsp;&nbsp;&nbsp; static_assert(*p =3D=3D 3);<br><br>&nbsp;=
&nbsp;&nbsp; int main()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp; /* loader() */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp; first_half();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete p;<=
br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; second_half();<br>&nbsp;&nbsp=
;&nbsp; }<br><br>In the above, for the duration of second_half() the resour=
ces used to back the predynamic object are available for use.&nbsp;  This i=
s achieved because preheap objects are loaded into the heap.&nbsp; Note the=
 .preheap section is unloaded by the end of `loader()`.<br><br>If we alloca=
ted it as a static storage duration object as you suggest, the resources wo=
uld still be occupied for second_half().<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_278_24444519.1381988352568--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 16 Oct 2013 23:43:23 -0700
Raw View
--nextPart2410628.QRZmiEjCmf
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On quarta-feira, 16 de outubro de 2013 22:39:12, Andrew Tomazos wrote:
> Such an architecture would use less resources.  Placing preheap objects in
> the heap allows them to be deleted during run-time, reclaiming their
> resources.  If we placed them in .rodata they could not be deleted.

It actually uses a different type of resource. Data stored in .rodata is
sharable, always clean memory that the OS virtual memory manager can discard
at will, since it can simply reload it from disk.

The regular heap, however, is unsharable memory that can become dirty (it can
be written to). If the OS virtual memory manager needs to reclaim pages and
this page is dirty, it will first need to write to the swap / pagefile.

In that sense, regular heap is more expensive to store the same bytes.

Add to that:
 - the overhead that malloc() has -- 8 to 32 bytes per allocation, depending
   on the implementation
 - the cost of calling malloc() during load-time (startup performance penalty)

>     typedef int T;
>
>     constexpr T* p = new T(3);
>
>     static_assert(*p == 3);
>
>     int main()
>     {
>
>         /* loader() */
>         first_half();
>         delete p;
>         second_half();
>
>     }

We don't need new in constexpr for that. The above program becomes better if
we replace constexpr with const, plus it will work with C++98.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--nextPart2410628.QRZmiEjCmf
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBSX4cSM/XwBW70U1gRAhrZAKCxPLm5MML1k0/ZP0IqjRY6evsh4ACgjH/k
kfSlZ9YUIYJ9Y6oEUAGNNds=
=c226
-----END PGP SIGNATURE-----

--nextPart2410628.QRZmiEjCmf--


.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 17 Oct 2013 00:20:30 -0700 (PDT)
Raw View
------=_Part_122_19820772.1381994430539
Content-Type: text/plain; charset=ISO-8859-1

On Thursday, October 17, 2013 8:43:23 AM UTC+2, Thiago Macieira wrote:
>
> On quarta-feira, 16 de outubro de 2013 22:39:12, Andrew Tomazos wrote:
> > Such an architecture would use less resources.  Placing preheap objects
> in
> > the heap allows them to be deleted during run-time, reclaiming their
> > resources.  If we placed them in .rodata they could not be deleted.
>
> It actually uses a different type of resource. Data stored in .rodata is
> sharable, always clean memory that the OS virtual memory manager can
> discard
> at will, since it can simply reload it from disk.
>

But if the .rodata section contains objects of static storage duration as
well as preheap objects then use of the static storage duration objects at
run-time will load the pages into memory, also unnecessarily loading any
preheap objects along with them.

The shareability is only helpful if you have multiple instances of the
program running simulatenously, in general that is not the case.  When only
running one instance of the program at once the swap file backs the heap
the same as the program image backs the .rodata section.  Also note that
preheap objects can be mutable, so actually what you are suggesting is
placing them in the .rodata, .bss or .data section as appropriate - the
read-only aspect is not relevant.

The regular heap, however, is unsharable memory that can become dirty (it
> can
> be written to). If the OS virtual memory manager needs to reclaim pages
> and
> this page is dirty, it will first need to write to the swap / pagefile.
>

Preheap objects can be written to.  They are not necessarily read-only.

In that sense, regular heap is more expensive to store the same bytes.
>
> Add to that:
>  - the overhead that malloc() has -- 8 to 32 bytes per allocation,
> depending
>    on the implementation
>  - the cost of calling malloc() during load-time (startup performance
> penalty)
>

Those overheads are implementation-dependant and generally not
asymptotically significant.

>     typedef int T;
> >
> >     constexpr T* p = new T(3);
> >
> >     static_assert(*p == 3);
> >
> >     int main()
> >     {
> >
> >         /* loader() */
> >         first_half();
> >         delete p;
> >         second_half();
> >
> >     }
>
> We don't need new in constexpr for that. The above program becomes better
> if
> we replace constexpr with const, plus it will work with C++98.
>

Then the static_assert wouldn't work, as the object wouldn't be a preheap
object, and would be unavailable during translation for use in constant
expressions.  That was the whole point of predynamic storage duration to
begin with.

--

---
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_122_19820772.1381994430539
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, October 17, 2013 8:43:23 AM UTC+2, Thiago Mac=
ieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On quarta-feira, 1=
6 de outubro de 2013 22:39:12, Andrew Tomazos wrote:
<br>&gt; Such an architecture would use less resources. &nbsp;Placing prehe=
ap objects in
<br>&gt; the heap allows them to be deleted during run-time, reclaiming the=
ir
<br>&gt; resources. &nbsp;If we placed them in .rodata they could not be de=
leted.
<br>
<br>It actually uses a different type of resource. Data stored in .rodata i=
s=20
<br>sharable, always clean memory that the OS virtual memory manager can di=
scard=20
<br>at will, since it can simply reload it from disk.
<br></blockquote><div>&nbsp;<br>But if the .rodata section contains objects=
 of static storage duration as well as preheap objects then use of the stat=
ic storage duration objects at run-time will load the pages into memory, al=
so unnecessarily loading any preheap objects along with them.<br><br>The sh=
areability is only helpful if you have multiple instances of the program ru=
nning simulatenously, in general that is not the case.&nbsp; When only runn=
ing one instance of the program at once the swap file backs the heap the sa=
me as the program image backs the .rodata section.&nbsp; Also note that pre=
heap objects can be mutable, so actually what you are suggesting is placing=
 them in the .rodata, .bss or .data section as appropriate - the read-only =
aspect is not relevant.<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;">The regular heap, however, is unsharable memory that can become dirt=
y (it can=20
<br>be written to). If the OS virtual memory manager needs to reclaim pages=
 and=20
<br>this page is dirty, it will first need to write to the swap / pagefile.=
=20
<br></blockquote><div>&nbsp;<br>Preheap objects can be written to.&nbsp; Th=
ey are not necessarily read-only.<br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">In that sense, regular heap is more expensive to store the=
 same bytes.
<br>
<br>Add to that:
<br>&nbsp;- the overhead that malloc() has -- 8 to 32 bytes per allocation,=
 depending=20
<br>&nbsp; &nbsp;on the implementation
<br>&nbsp;- the cost of calling malloc() during load-time (startup performa=
nce penalty)
<br></blockquote><div>&nbsp;<br>Those overheads are implementation-dependan=
t and generally not asymptotically significant.<br><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;">&gt; &nbsp; &nbsp; typedef int T;
<br>&gt; &nbsp; &nbsp;=20
<br>&gt; &nbsp; &nbsp; constexpr T* p =3D new T(3);
<br>&gt; &nbsp; &nbsp;=20
<br>&gt; &nbsp; &nbsp; static_assert(*p =3D=3D 3);
<br>&gt; &nbsp; &nbsp;=20
<br>&gt; &nbsp; &nbsp; int main()
<br>&gt; &nbsp; &nbsp; {
<br>&gt; &nbsp; &nbsp;=20
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; /* loader() */
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; first_half();
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; delete p;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; second_half();
<br>&gt; &nbsp; &nbsp;=20
<br>&gt; &nbsp; &nbsp; }
<br>
<br>We don't need new in constexpr for that. The above program becomes bett=
er if=20
<br>we replace constexpr with const, plus it will work with C++98.
<br></blockquote><div><br>Then the static_assert wouldn't work, as the obje=
ct wouldn't be a preheap object, and would be unavailable during translatio=
n for use in constant expressions.&nbsp; That was the whole point of predyn=
amic storage duration to begin with.<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_122_19820772.1381994430539--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 17 Oct 2013 00:24:35 -0700 (PDT)
Raw View
------=_Part_320_1488161.1381994675051
Content-Type: text/plain; charset=ISO-8859-1



On Thursday, October 17, 2013 9:20:30 AM UTC+2, Andrew Tomazos wrote:
>
> On Thursday, October 17, 2013 8:43:23 AM UTC+2, Thiago Macieira wrote:
>


> In that sense, regular heap is more expensive to store the same bytes.
>
>>
>> Add to that:
>>  - the overhead that malloc() has -- 8 to 32 bytes per allocation,
>> depending
>>    on the implementation
>>  - the cost of calling malloc() during load-time (startup performance
>> penalty)
>>
>
> Those overheads are implementation-dependant and generally not
> asymptotically significant.
>
> Sorry, I meant the first one.  Yes the cost of loading them may be
significant, but it is no different to the cost of initializing a
std::string with a string literal now.  The point is preheap objects can be
used during translation and run-time.  Dynamic storage duration objects are
not available during translation currently.


--

---
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_320_1488161.1381994675051
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, October 17, 2013 9:20:30 AM UTC+2, An=
drew Tomazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">On Thursday, October 17, 2013 8:43:23 AM UTC+2, Thiago Macieira wrote=
:</div></blockquote><div>&nbsp;</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">In that sense, regular heap is more expensive to st=
ore the same bytes.
<br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex">
<br>Add to that:
<br>&nbsp;- the overhead that malloc() has -- 8 to 32 bytes per allocation,=
 depending=20
<br>&nbsp; &nbsp;on the implementation
<br>&nbsp;- the cost of calling malloc() during load-time (startup performa=
nce penalty)
<br></blockquote><div>&nbsp;<br>Those overheads are implementation-dependan=
t and generally not asymptotically significant.<br><br></div></div></blockq=
uote><div>Sorry, I meant the first one.&nbsp; Yes the cost of loading them =
may be significant, but it is no different to the cost of initializing a st=
d::string with a string literal now.&nbsp; The point is preheap objects can=
 be used during translation and run-time.&nbsp; Dynamic storage duration ob=
jects are not available during translation currently.<br><br><br></div></di=
v>

<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_320_1488161.1381994675051--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Thu, 17 Oct 2013 00:55:34 -0700
Raw View
--e89a8ff1c99e7f6dd104e8eb2488
Content-Type: text/plain; charset=ISO-8859-1

Erm, *none* of these things are asymptotically sufficient.

All of this talk about binary sections sounds awfully platform specific for
the standard at this point. You're talking about ELF sections, right? Not
all platforms use ELF. As I said earlier, none of this is going to be
significant in run time in the real world. If the point is to allow the
types to be constexpr that's interesting, but the question there is "how
does the constexpr language feature interact with operator new inside
string/vector", not where in the binary various things go. The standard
defines language semantics, not binary layout.

Another possible implementation would be to have no binary preheap concept.
Instead, it is transformed by the compiler to generate the correct memory
state at run time, which may involve calls to operator new. If involved in
something constexpr, the compiler could figure out the right answers, but
the behavior under constexpr and non constexpr conditions could be
completely different.

--

---
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/.

--e89a8ff1c99e7f6dd104e8eb2488
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr">Erm, *none* of these things are asymptotically sufficient.</=
p>
<p dir=3D"ltr">All of this talk about binary sections sounds awfully platfo=
rm specific for the standard at this point. You&#39;re talking about ELF se=
ctions, right? Not all platforms use ELF. As I said earlier, none of this i=
s going to be significant in run time in the real world. If the point is to=
 allow the types to be constexpr that&#39;s interesting, but the question t=
here is &quot;how does the constexpr language feature interact with operato=
r new inside string/vector&quot;, not where in the binary various things go=
.. The standard defines language semantics, not binary layout.</p>

<p dir=3D"ltr">Another possible implementation would be to have no binary p=
reheap concept. Instead, it is transformed by the compiler to generate the =
correct memory state at run time, which may involve calls to operator new. =
If involved in something constexpr, the compiler could figure out the right=
 answers, but the behavior under constexpr and non constexpr conditions cou=
ld be completely different.</p>

<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 />

--e89a8ff1c99e7f6dd104e8eb2488--

.