Topic: constexpr! or constexpr(false)?


Author: gmisocpp@gmail.com
Date: Mon, 9 Jul 2018 17:01:42 -0700 (PDT)
Raw View
------=_Part_110151_293883128.1531180902210
Content-Type: multipart/alternative;
 boundary="----=_Part_110152_1381630234.1531180902211"

------=_Part_110152_1381630234.1531180902211
Content-Type: text/plain; charset="UTF-8"

Hello everyone

Have the authors of p10731r.html considered if this suggestion:

constexpr(true) int sqr(int n) {
  return n*n;
}

is preferable and more consistent or flexible than this which they
currently propose:

constexpr! int sqr(int n) {
  return n*n;
}

And would it offer the following possibility and would it be useful?:

constexpr(some_condition()) int sqr(int n) { // constexpr this function on
certain conditions.
  return n*n;
}

Also many compilers support forceinline functionality etc. Perhaps this
should be standardized too now?
Therefore I think the authors might want to propose this too:

inline(false) int sqr(int n) { // force inline. Or inline! if the committee
thinks best.
  return n*n;
}

Which might similarly allow this?:
inline(some_other_condiition()) int sqr(int n) { // force inline. Or
inline! if the committee thinks best.
  return n*n;
}

where some_other_condition might test for a certain platform or compile
where forcing inline or not might be desirable despite what the compiler
thinks.

It seems to me using ! is a little unusual syntax and be less consistent
and flexible than what I'm proposing but I admit ! is shorter.

I see such macros regarding forceinline in various code bases such as
libcxx's __config file. So perhaps forceinline's time has come too.

What do the authors of p1073r1 and others think?

Thanks

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b3ebfe97-48ae-4a85-b202-2dbf330dd76b%40isocpp.org.

------=_Part_110152_1381630234.1531180902211
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello everyone</div><div><br>Have the authors of=C2=
=A0p10731r.html considered if this suggestion:</div><div><br></div><p>const=
expr(true) int sqr(int n) {<br>=C2=A0 return n*n;<br>}</p><div><br></div><d=
iv>is preferable and more consistent or flexible than this which=C2=A0they =
currently propose:</div><div><br></div><div>constexpr! int sqr(int n) {<br>=
=C2=A0 return n*n;<br>}</div><div><br></div><div>And would=C2=A0it offer=C2=
=A0the following=C2=A0possibility and would it be useful?:</div><div><br></=
div><div>constexpr(some_condition()) int sqr(int n) { //=C2=A0constexpr thi=
s function=C2=A0on certain=C2=A0conditions.<br>=C2=A0 return n*n;<br>}</div=
><div><br>Also=C2=A0many compilers support=C2=A0forceinline functionality e=
tc. Perhaps this should be standardized too now?</div><div>Therefore I thin=
k the authors might want to=C2=A0propose this too:</div><div><br></div><div=
>inline(false) int sqr(int n) { // force inline. Or inline! if the committe=
e thinks best.<br>=C2=A0 return n*n;<br>}</div><div><br></div><div>Which mi=
ght similarly allow this?:</div><div>inline(some_other_condiition()) int sq=
r(int n) { // force inline. Or inline! if the committee thinks best.<br>=C2=
=A0 return n*n;<br>}</div><div><br></div><div>where some_other_condition mi=
ght=C2=A0test for a certain platform or compile where forcing inline or not=
 might be desirable despite what the compiler thinks.</div><div><br></div><=
div>It seems to me using ! is a little unusual syntax=C2=A0and be less cons=
istent and flexible than what I&#39;m proposing but=C2=A0I admit ! is short=
er.</div><div><div><br></div><div>I see such macros regarding forceinline i=
n various code bases such as libcxx&#39;s __config file. So perhaps forcein=
line&#39;s time has come too.</div></div><div><br></div><div>What do the au=
thors of=C2=A0p1073r1 and others think?</div><div><br></div><div>Thanks<br>=
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b3ebfe97-48ae-4a85-b202-2dbf330dd76b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b3ebfe97-48ae-4a85-b202-2dbf330dd76b=
%40isocpp.org</a>.<br />

------=_Part_110152_1381630234.1531180902211--

------=_Part_110151_293883128.1531180902210--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 10 Jul 2018 03:10:25 +0300
Raw View
On 10 July 2018 at 03:01,  <gmisocpp@gmail.com> wrote:
> Hello everyone
>
> Have the authors of p10731r.html considered if this suggestion:
>
> constexpr(true) int sqr(int n) {
>   return n*n;
> }

I hear that a certain committee member suggested that "these are true
constexpr functions, so spelling it
as 'true constexpr' would make a fair amount of sense". It was
discussed in Rapperswil, and the results were
as follows:

Propose as presented for C++20

SF F N A SA
19 22 1 2 0

Use =E2=80=9Ctrue constexpr=E2=80=9D instead of =E2=80=9Cconstexpr!=E2=80=
=9D

SF F N A SA
5 8 14 8 10


> And would it offer the following possibility and would it be useful?:
>
> constexpr(some_condition()) int sqr(int n) { // constexpr this function o=
n
> certain conditions.
>   return n*n;
> }

I don't know what I'd use that for. A constexpr function can already
be constexpr on certain conditions,
but I don't know why I'd ever make a function conditionally 'true
constexpr'. If I need a 'true constexpr'
function, a 'non-true constexpr' function will not do, but if I need a
normal constexpr function, either
a normal or a 'true' constexpr function will both do.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAFk2RUZKeomj2cVywH3Bhpu%2BLCTNx09m6gVNxLvPiwceD=
8agNQ%40mail.gmail.com.

.


Author: gmisocpp@gmail.com
Date: Mon, 9 Jul 2018 20:45:48 -0700 (PDT)
Raw View
------=_Part_115388_1705783267.1531194348240
Content-Type: multipart/alternative;
 boundary="----=_Part_115389_439583457.1531194348240"

------=_Part_115389_439583457.1531194348240
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Tuesday, July 10, 2018 at 12:10:27 PM UTC+12, Ville Voutilainen wrote:
>
> On 10 July 2018 at 03:01,  <gmis...@gmail.com <javascript:>> wrote:=20
> > Hello everyone=20
> >=20
> > Have the authors of p10731r.html considered if this suggestion:=20
> >=20
> > constexpr(true) int sqr(int n) {=20
> >   return n*n;=20
> > }=20
>
> I hear that a certain committee member suggested that "these are true=20
> constexpr functions, so spelling it=20
> as 'true constexpr' would make a fair amount of sense". It was=20
> discussed in Rapperswil, and the results were=20
> as follows:=20
>
> Propose as presented for C++20=20
>
> SF F N A SA=20
> 19 22 1 2 0=20
>
> Use =E2=80=9Ctrue constexpr=E2=80=9D instead of =E2=80=9Cconstexpr!=E2=80=
=9D=20
>
> SF F N A SA=20
> 5 8 14 8 10=20
>
>
> > And would it offer the following possibility and would it be useful?:=
=20
> >=20
> > constexpr(some_condition()) int sqr(int n) { // constexpr this function=
=20
> on=20
> > certain conditions.=20
> >   return n*n;=20
> > }=20
>
> I don't know what I'd use that for. A constexpr function can already=20
> be constexpr on certain conditions,=20
> but I don't know why I'd ever make a function conditionally 'true=20
> constexpr'. If I need a 'true constexpr'=20
> function, a 'non-true constexpr' function will not do, but if I need a=20
> normal constexpr function, either=20
> a normal or a 'true' constexpr function will both do.=20
>

I suspect you are correct about needing one constexpr or the other.

However, it seems to inline or not is something you might want to do=20
depending on the platform or compilers ability.
But perhaps #ifdef is the tool for that. But aren't we trying to get a way=
=20
from the pre-processor?
I hope inline! or inline(true) is something that should can be standardized=
=20
to replace __forceinline etc.
=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/303bf6d1-2f5a-4b50-b6c0-6d689300243c%40isocpp.or=
g.

------=_Part_115389_439583457.1531194348240
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, July 10, 2018 at 12:10:27 PM UTC+12, V=
ille Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204);=
 border-left-width: 1px; border-left-style: solid;">On 10 July 2018 at 03:0=
1, =C2=A0&lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"java=
script:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"w9rIR1=
XsBQAJ">gmis...@gmail.com</a>&gt; wrote:
<br>&gt; Hello everyone
<br>&gt;
<br>&gt; Have the authors of p10731r.html considered if this suggestion:
<br>&gt;
<br>&gt; constexpr(true) int sqr(int n) {
<br>&gt; =C2=A0 return n*n;
<br>&gt; }
<br>
<br>I hear that a certain committee member suggested that &quot;these are t=
rue
<br>constexpr functions, so spelling it
<br>as &#39;true constexpr&#39; would make a fair amount of sense&quot;. It=
 was
<br>discussed in Rapperswil, and the results were
<br>as follows:
<br>
<br>Propose as presented for C++20
<br>
<br>SF F N A SA
<br>19 22 1 2 0
<br>
<br>Use =E2=80=9Ctrue constexpr=E2=80=9D instead of =E2=80=9Cconstexpr!=E2=
=80=9D
<br>
<br>SF F N A SA
<br>5 8 14 8 10
<br>
<br>
<br>&gt; And would it offer the following possibility and would it be usefu=
l?:
<br>&gt;
<br>&gt; constexpr(some_condition()) int sqr(int n) { // constexpr this fun=
ction on
<br>&gt; certain conditions.
<br>&gt; =C2=A0 return n*n;
<br>&gt; }
<br>
<br>I don&#39;t know what I&#39;d use that for. A constexpr function can al=
ready
<br>be constexpr on certain conditions,
<br>but I don&#39;t know why I&#39;d ever make a function conditionally &#3=
9;true
<br>constexpr&#39;. If I need a &#39;true constexpr&#39;
<br>function, a &#39;non-true constexpr&#39; function will not do, but if I=
 need a
<br>normal constexpr function, either
<br>a normal or a &#39;true&#39; constexpr function will both do.
<br></blockquote><div><br></div><div>I suspect you are correct about needin=
g=C2=A0one constexpr=C2=A0or the other.</div><div><br></div><div>However,=
=C2=A0it seems=C2=A0to inline or not is something=C2=A0you might want to do=
 depending on=C2=A0the platform or compilers ability.</div><div>But perhaps=
 #ifdef is the tool for that. But aren&#39;t we trying to get a way from th=
e pre-processor?</div><div>I hope=C2=A0inline! or inline(true) is something=
 that should can be standardized to replace=C2=A0__forceinline etc.</div><d=
iv>=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/303bf6d1-2f5a-4b50-b6c0-6d689300243c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/303bf6d1-2f5a-4b50-b6c0-6d689300243c=
%40isocpp.org</a>.<br />

------=_Part_115389_439583457.1531194348240--

------=_Part_115388_1705783267.1531194348240--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Tue, 10 Jul 2018 23:57:21 +0200
Raw View
On Tue, Jul 10, 2018 at 03:10:25AM +0300, Ville Voutilainen wrote:
> On 10 July 2018 at 03:01,  <gmisocpp@gmail.com> wrote:
> > Hello everyone
> >
> > Have the authors of p10731r.html considered if this suggestion:
> >
> > constexpr(true) int sqr(int n) {
> >   return n*n;
> > }
>=20
> I hear that a certain committee member suggested that "these are true
> constexpr functions, so spelling it
> as 'true constexpr' would make a fair amount of sense". It was
> discussed in Rapperswil, and the results were
> as follows:
>=20
> Propose as presented for C++20
>=20
> SF F N A SA
> 19 22 1 2 0
>=20
> Use =E2=80=9Ctrue constexpr=E2=80=9D instead of =E2=80=9Cconstexpr!=E2=80=
=9D
>=20
> SF F N A SA
> 5 8 14 8 10
>=20

Is 'constexpr not' as in

constexpr not int sqr(int n) { return n*n; }

a valid spelling of constexpr! ?

/MF

>=20
> > And would it offer the following possibility and would it be useful?:
> >
> > constexpr(some_condition()) int sqr(int n) { // constexpr this function=
 on
> > certain conditions.
> >   return n*n;
> > }
>=20
> I don't know what I'd use that for. A constexpr function can already
> be constexpr on certain conditions,
> but I don't know why I'd ever make a function conditionally 'true
> constexpr'. If I need a 'true constexpr'
> function, a 'non-true constexpr' function will not do, but if I need a
> normal constexpr function, either
> a normal or a 'true' constexpr function will both do.
>=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=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/CAFk2RUZKeomj2cVywH3Bhpu%2BLCTNx09m6gVNxLvPiwc=
eD8agNQ%40mail.gmail.com.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/20180710215721.GA29273%40noemi.bahnhof.se.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 11 Jul 2018 01:09:22 +0300
Raw View
On 11 July 2018 at 00:57, Magnus Fromreide <magfr@lysator.liu.se> wrote:
> Is 'constexpr not' as in
>
> constexpr not int sqr(int n) { return n*n; }
>
> a valid spelling of constexpr! ?

No.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUaquLcts7ea2wr-iV5fHvNv%3D2sRr_8uMRVteZEwc%2BxtoQ%40mail.gmail.com.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 10 Jul 2018 19:58:43 -0400
Raw View
--000000000000f4ea510570ade896
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Mon, Jul 9, 2018 at 11:45 PM, <gmisocpp@gmail.com> wrote:

>
>
> On Tuesday, July 10, 2018 at 12:10:27 PM UTC+12, Ville Voutilainen wrote:
>
>> On 10 July 2018 at 03:01,  <gmis...@gmail.com> wrote:
>> > Hello everyone
>> >
>> > Have the authors of p10731r.html considered if this suggestion:
>> >
>> > constexpr(true) int sqr(int n) {
>> >   return n*n;
>> > }
>>
>> I hear that a certain committee member suggested that "these are true
>> constexpr functions, so spelling it
>> as 'true constexpr' would make a fair amount of sense". It was
>> discussed in Rapperswil, and the results were
>> as follows:
>>
>> Propose as presented for C++20
>>
>> SF F N A SA
>> 19 22 1 2 0
>>
>> Use =E2=80=9Ctrue constexpr=E2=80=9D instead of =E2=80=9Cconstexpr!=E2=
=80=9D
>>
>> SF F N A SA
>> 5 8 14 8 10
>>
>>
>> > And would it offer the following possibility and would it be useful?:
>> >
>> > constexpr(some_condition()) int sqr(int n) { // constexpr this functio=
n
>> on
>> > certain conditions.
>> >   return n*n;
>> > }
>>
>> I don't know what I'd use that for. A constexpr function can already
>> be constexpr on certain conditions,
>> but I don't know why I'd ever make a function conditionally 'true
>> constexpr'. If I need a 'true constexpr'
>> function, a 'non-true constexpr' function will not do, but if I need a
>> normal constexpr function, either
>> a normal or a 'true' constexpr function will both do.
>>
>
> I suspect you are correct about needing one constexpr or the other.
>
> However, it seems to inline or not is something you might want to do
> depending on the platform or compilers ability.
> But perhaps #ifdef is the tool for that. But aren't we trying to get a wa=
y
> from the pre-processor?
> I hope inline! or inline(true) is something that should can be
> standardized to replace __forceinline etc.
>


I don't think we can standardize anything to replace __forceinline.
It has no meaning to the abstract machine.
The "as-if" rule means you can't tell (by running the code) whether it was
inlined.
For example, what if my implementation is an interpreter, not a compiler?
What does inline mean then?


--=20
Be seeing you,
Tony

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOHCbite6NDoLNGA__iVZ7GCS9EYCavBcGPPiqWfd9DH0%2=
BqvBQ%40mail.gmail.com.

--000000000000f4ea510570ade896
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Jul 9, 2018 at 11:45 PM,  <span dir=3D"ltr">&lt;<a href=3D"mail=
to:gmisocpp@gmail.com" target=3D"_blank">gmisocpp@gmail.com</a>&gt;</span> =
wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Tuesda=
y, July 10, 2018 at 12:10:27 PM UTC+12, Ville Voutilainen wrote:<div><div c=
lass=3D"h5"><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-left-style:solid">On 10 July 2018 at 03:01, =C2=A0&lt;<a rel=3D"=
nofollow">gmis...@gmail.com</a>&gt; wrote:
<br>&gt; Hello everyone
<br>&gt;
<br>&gt; Have the authors of p10731r.html considered if this suggestion:
<br>&gt;
<br>&gt; constexpr(true) int sqr(int n) {
<br>&gt; =C2=A0 return n*n;
<br>&gt; }
<br>
<br>I hear that a certain committee member suggested that &quot;these are t=
rue
<br>constexpr functions, so spelling it
<br>as &#39;true constexpr&#39; would make a fair amount of sense&quot;. It=
 was
<br>discussed in Rapperswil, and the results were
<br>as follows:
<br>
<br>Propose as presented for C++20
<br>
<br>SF F N A SA
<br>19 22 1 2 0
<br>
<br>Use =E2=80=9Ctrue constexpr=E2=80=9D instead of =E2=80=9Cconstexpr!=E2=
=80=9D
<br>
<br>SF F N A SA
<br>5 8 14 8 10
<br>
<br>
<br>&gt; And would it offer the following possibility and would it be usefu=
l?:
<br>&gt;
<br>&gt; constexpr(some_condition()) int sqr(int n) { // constexpr this fun=
ction on
<br>&gt; certain conditions.
<br>&gt; =C2=A0 return n*n;
<br>&gt; }
<br>
<br>I don&#39;t know what I&#39;d use that for. A constexpr function can al=
ready
<br>be constexpr on certain conditions,
<br>but I don&#39;t know why I&#39;d ever make a function conditionally &#3=
9;true
<br>constexpr&#39;. If I need a &#39;true constexpr&#39;
<br>function, a &#39;non-true constexpr&#39; function will not do, but if I=
 need a
<br>normal constexpr function, either
<br>a normal or a &#39;true&#39; constexpr function will both do.
<br></blockquote><div><br></div></div></div><div>I suspect you are correct =
about needing=C2=A0one constexpr=C2=A0or the other.</div><div><br></div><di=
v>However,=C2=A0it seems=C2=A0to inline or not is something=C2=A0you might =
want to do depending on=C2=A0the platform or compilers ability.</div><div>B=
ut perhaps #ifdef is the tool for that. But aren&#39;t we trying to get a w=
ay from the pre-processor?</div><div>I hope=C2=A0inline! or inline(true) is=
 something that should can be standardized to replace=C2=A0__forceinline et=
c.</div></div></blockquote><div><br></div><div><br></div><div>I don&#39;t t=
hink we can standardize anything to replace __forceinline.</div><div>It has=
 no meaning to the abstract machine.<br></div><div>The &quot;as-if&quot; ru=
le means you can&#39;t tell (by running the code) whether it was inlined.</=
div><div>For example, what if my implementation is an interpreter, not a co=
mpiler? What does inline mean then?<br></div><br clear=3D"all"></div><br>--=
 <br><div class=3D"gmail_signature" data-smartmail=3D"gmail_signature"><div=
 dir=3D"ltr"><div>Be seeing you,<br></div>Tony<br></div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOHCbite6NDoLNGA__iVZ7GCS9EYCavBcGPP=
iqWfd9DH0%2BqvBQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbite6NDoLN=
GA__iVZ7GCS9EYCavBcGPPiqWfd9DH0%2BqvBQ%40mail.gmail.com</a>.<br />

--000000000000f4ea510570ade896--

.


Author: gmisocpp@gmail.com
Date: Tue, 10 Jul 2018 20:20:53 -0700 (PDT)
Raw View
------=_Part_71643_1396188452.1531279253186
Content-Type: multipart/alternative;
 boundary="----=_Part_71644_654013295.1531279253187"

------=_Part_71644_654013295.1531279253187
Content-Type: text/plain; charset="UTF-8"


>
>
> I don't think we can standardize anything to replace __forceinline.
> It has no meaning to the abstract machine.
> The "as-if" rule means you can't tell (by running the code) whether it was
> inlined.
> For example, what if my implementation is an interpreter, not a compiler?
> What does inline mean then?
>
>
> --
> Be seeing you,
> Tony
>

I don't understand the problem.
But do we have to specify what it means in any detail?
What's wrong with inline! meaning "if you can inline this function by any
means, do so. If it really can't be forced inline act as inline".
I would expect compilers issue a warning and behave in whatever way inline
would have.

Why would this stop an interpreter?


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e44c4cfc-b27f-4301-89c6-dbf894570db9%40isocpp.org.

------=_Part_71644_654013295.1531279253187
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div><div cl=
ass=3D"gmail_quote"><div><br></div><div>I don&#39;t think we can standardiz=
e anything to replace __forceinline.</div><div>It has no meaning to the abs=
tract machine.<br></div><div>The &quot;as-if&quot; rule means you can&#39;t=
 tell (by running the code) whether it was inlined.</div><div>For example, =
what if my implementation is an interpreter, not a compiler? What does inli=
ne mean then?<br></div><br clear=3D"all"></div><br>-- <br><div><div dir=3D"=
ltr"><div>Be seeing you,<br></div>Tony<br></div></div></div></div></blockqu=
ote><div><br></div><div>I don&#39;t understand the problem.</div><div>But=
=C2=A0do we have to=C2=A0specify what it means in any detail?</div><div>Wha=
t&#39;s wrong with inline! meaning=C2=A0&quot;if you can inline this functi=
on by any means, do so. If it really can&#39;t be forced inline act as inli=
ne&quot;.</div><div>I would expect=C2=A0compilers=C2=A0issue a warning and =
behave in whatever way inline would have.</div><div><br></div><div>Why woul=
d this stop an interpreter?</div><div><br></div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e44c4cfc-b27f-4301-89c6-dbf894570db9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e44c4cfc-b27f-4301-89c6-dbf894570db9=
%40isocpp.org</a>.<br />

------=_Part_71644_654013295.1531279253187--

------=_Part_71643_1396188452.1531279253186--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 10 Jul 2018 21:54:15 -0700 (PDT)
Raw View
------=_Part_96229_1166624066.1531284855591
Content-Type: multipart/alternative;
 boundary="----=_Part_96230_1677610723.1531284855592"

------=_Part_96230_1677610723.1531284855592
Content-Type: text/plain; charset="UTF-8"

On Tuesday, July 10, 2018 at 11:20:53 PM UTC-4, gmis...@gmail.com wrote:
>
>
>> I don't think we can standardize anything to replace __forceinline.
>> It has no meaning to the abstract machine.
>> The "as-if" rule means you can't tell (by running the code) whether it
>> was inlined.
>> For example, what if my implementation is an interpreter, not a compiler?
>> What does inline mean then?
>>
>>
>> --
>> Be seeing you,
>> Tony
>>
>
> I don't understand the problem.
> But do we have to specify what it means in any detail?
>

Because that's what a specification is: specifying behavior in sufficient
detail.

What's wrong with inline! meaning "if you can inline this function by any
> means, do so. If it really can't be forced inline act as inline".
>

Because then you have to define what it means to "inline a function" and
how that relates to the abstract machine.


> I would expect compilers issue a warning and behave in whatever way inline
> would have.
>
> Why would this stop an interpreter?
>

Because the concept of "inline a function" is primarily built around code
generation. A function is inlined by generating its code at each call site.

In an interpreter, there is no code generation. You just have a
post-compiled AST, which your interpreter walks through. "Inlining" has no
meaning here, but the C++ abstract machine still does.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f9a97563-31dc-480a-8846-e83ede139c26%40isocpp.org.

------=_Part_96230_1677610723.1531284855592
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, July 10, 2018 at 11:20:53 PM UTC-4, gmis...@gm=
ail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;paddin=
g-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-=
left-style:solid"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br=
></div><div>I don&#39;t think we can standardize anything to replace __forc=
einline.</div><div>It has no meaning to the abstract machine.<br></div><div=
>The &quot;as-if&quot; rule means you can&#39;t tell (by running the code) =
whether it was inlined.</div><div>For example, what if my implementation is=
 an interpreter, not a compiler? What does inline mean then?<br></div><br c=
lear=3D"all"></div><br>-- <br><div><div dir=3D"ltr"><div>Be seeing you,<br>=
</div>Tony<br></div></div></div></div></blockquote><div><br></div><div>I do=
n&#39;t understand the problem.</div><div>But=C2=A0do we have to=C2=A0speci=
fy what it means in any detail?</div></div></blockquote><div><br></div><div=
>Because that&#39;s what a specification is: specifying behavior in suffici=
ent detail.<br></div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>What&#39;s wrong with inline! meaning=C2=A0&quo=
t;if you can inline this function by any means, do so. If it really can&#39=
;t be forced inline act as inline&quot;.</div></div></blockquote><div><br><=
/div><div>Because then you have to define what it means to &quot;inline a f=
unction&quot; and how that relates to the abstract machine.<br></div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div>I would expect=C2=A0compilers=C2=A0issue a warning and behave in whatev=
er way inline would have.</div><div><br></div><div>Why would this stop an i=
nterpreter?</div></div></blockquote><div><br></div><div>Because the concept=
 of &quot;inline a function&quot; is primarily built around code generation=
.. A function is inlined by generating its code at each call site.</div><div=
><br></div><div>In an interpreter, there is no code generation. You just ha=
ve a post-compiled AST, which your interpreter walks through. &quot;Inlinin=
g&quot; has no meaning here, but the C++ abstract machine still does.<br></=
div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f9a97563-31dc-480a-8846-e83ede139c26%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f9a97563-31dc-480a-8846-e83ede139c26=
%40isocpp.org</a>.<br />

------=_Part_96230_1677610723.1531284855592--

------=_Part_96229_1166624066.1531284855591--

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jul 2018 00:14:01 -0700 (PDT)
Raw View
------=_Part_125219_260823385.1531293241469
Content-Type: multipart/alternative;
 boundary="----=_Part_125220_321712445.1531293241469"

------=_Part_125220_321712445.1531293241469
Content-Type: text/plain; charset="UTF-8"



On Wednesday, July 11, 2018 at 4:54:15 PM UTC+12, Nicol Bolas wrote:
>
> On Tuesday, July 10, 2018 at 11:20:53 PM UTC-4, gmis...@gmail.com wrote:
>>
>>
>>> I don't think we can standardize anything to replace __forceinline.
>>> It has no meaning to the abstract machine.
>>> The "as-if" rule means you can't tell (by running the code) whether it
>>> was inlined.
>>> For example, what if my implementation is an interpreter, not a
>>> compiler? What does inline mean then?
>>>
>>>
>>> --
>>> Be seeing you,
>>> Tony
>>>
>>
>> I don't understand the problem.
>> But do we have to specify what it means in any detail?
>>
>
> Because that's what a specification is: specifying behavior in sufficient
> detail.
>

Sounds patronising.
There are plenty of things that are in C++ that are specified as
unspecified or implementation defined etc. But it's irrelevant to what I
actually suggested anyway.


>
> What's wrong with inline! meaning "if you can inline this function by any
>> means, do so. If it really can't be forced inline act as inline".
>>
>
> Because then you have to define what it means to "inline a function" and
> how that relates to the abstract machine.
>

We know what it means to inline a function, it's called inline.


>
>
>> I would expect compilers issue a warning and behave in whatever way
>> inline would have.
>>
>> Why would this stop an interpreter?
>>
>
> Because the concept of "inline a function" is primarily built around code
> generation. A function is inlined by generating its code at each call site.
>
> In an interpreter, there is no code generation. You just have a
> post-compiled AST, which your interpreter walks through. "Inlining" has no
> meaning here, but the C++ abstract machine still does.
>

inline is already in the standard, so again why is inline! as a try harder
to inline directive that resorts to inline if it can't, an impossible thing
when we already have inline and many implementations have __forceinline or
always_inline etc.?
If interpreter or non interpreter "can't" it'd do what inline does.

Where's the problem?


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a8f4b2c0-d025-4973-98d7-6a60b8071068%40isocpp.org.

------=_Part_125220_321712445.1531293241469
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 4:54:15 PM UTC+12, =
Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0p=
x 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); bord=
er-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr">On Tuesday,=
 July 10, 2018 at 11:20:53 PM UTC-4, <a>gmis...@gmail.com</a> wrote:<blockq=
uote 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; borde=
r-left-style: solid;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" st=
yle=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 di=
r=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div><div>I don&#39;t t=
hink we can standardize anything to replace __forceinline.</div><div>It has=
 no meaning to the abstract machine.<br></div><div>The &quot;as-if&quot; ru=
le means you can&#39;t tell (by running the code) whether it was inlined.</=
div><div>For example, what if my implementation is an interpreter, not a co=
mpiler? What does inline mean then?<br></div><br clear=3D"all"></div><br>--=
 <br><div><div dir=3D"ltr"><div>Be seeing you,<br></div>Tony<br></div></div=
></div></div></blockquote><div><br></div><div>I don&#39;t understand the pr=
oblem.</div><div>But=C2=A0do we have to=C2=A0specify what it means in any d=
etail?</div></div></blockquote><div><br></div><div>Because that&#39;s what =
a specification is: specifying behavior in sufficient detail.<br></div></di=
v></blockquote><div><br></div><div>Sounds patronising.</div><div>There are =
plenty of things that are in C++ that are specified as unspecified or imple=
mentation defined etc. But it&#39;s irrelevant to what I actually suggested=
 anyway.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 20=
4, 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr=
"><div></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, =
204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><=
div>What&#39;s wrong with inline! meaning=C2=A0&quot;if you can inline this=
 function by any means, do so. If it really can&#39;t be forced inline act =
as inline&quot;.</div></div></blockquote><div><br></div><div>Because then y=
ou have to define what it means to &quot;inline a function&quot; and how th=
at relates to the abstract machine.<br></div></div></blockquote><div><br></=
div><div>We know what it means to inline a function, it&#39;s called inline=
..</div><div>=C2=A0</div><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-left-style: solid;"><div dir=3D"ltr"><div>=
</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204);=
 border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>I=
 would expect=C2=A0compilers=C2=A0issue a warning and behave in whatever wa=
y inline would have.</div><div><br></div><div>Why would this stop an interp=
reter?</div></div></blockquote><div><br></div><div>Because the concept of &=
quot;inline a function&quot; is primarily built around code generation. A f=
unction is inlined by generating its code at each call site.</div><div><br>=
</div><div>In an interpreter, there is no code generation. You just have a =
post-compiled AST, which your interpreter walks through. &quot;Inlining&quo=
t; has no meaning here, but the C++ abstract machine still does.<br></div><=
/div></blockquote><div><br></div><div>inline is already in the standard, so=
 again why is inline! as=C2=A0a try harder to inline directive that resorts=
 to inline=C2=A0if it can&#39;t, an impossible thing when we already have i=
nline and many implementations have __forceinline or always_inline etc.?</d=
iv><div>If=C2=A0interpreter or non interpreter=C2=A0&quot;can&#39;t&quot; i=
t&#39;d do what inline does.</div><div><br></div><div>Where&#39;s the probl=
em?</div><div><br></div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a8f4b2c0-d025-4973-98d7-6a60b8071068%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a8f4b2c0-d025-4973-98d7-6a60b8071068=
%40isocpp.org</a>.<br />

------=_Part_125220_321712445.1531293241469--

------=_Part_125219_260823385.1531293241469--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 11 Jul 2018 03:28:40 -0400
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
 255, 255); line-height: initial;">                                        =
                                              <div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">If inline! is allowed to fall back to inline, than inline! woul=
d be no better than inline.</div><div style=3D"width: 100%; font-size: init=
ial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(=
31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">B=
ecause that's what the current inline already does: inline if you can (or '=
want').</div><div style=3D"width: 100%; font-size: initial; font-family: Ca=
libri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-a=
lign: initial; background-color: rgb(255, 255, 255);"><br></div><div style=
=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', san=
s-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backgrou=
nd-color: rgb(255, 255, 255);"><span style=3D"font-size: initial; text-alig=
n: initial; line-height: initial;"><br></span></div><div style=3D"width: 10=
0%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans=
-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb=
(255, 255, 255);"><span style=3D"font-size: initial; text-align: initial; l=
ine-height: initial;">You can say there's a difference between 'can' and 'w=
ant', but there isn't. Compilers are always free to do things if you can wr=
ite code that detects what it did and prints out the difference. The 'as-if=
' rule.</span></div><div style=3D"width: 100%; font-size: initial; font-fam=
ily: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125);=
 text-align: initial; background-color: rgb(255, 255, 255);"><br></div><div=
 style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro=
', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; ba=
ckground-color: rgb(255, 255, 255);">And what does inline *really* mean cur=
rently? It doesn't mean inline the code, it means don't complain about mult=
iple definitions of the same function. That's why we recently decided to us=
e it on variables. </div><div style=3D"width: 100%; font-size: initial; fon=
t-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, =
125); text-align: initial; background-color: rgb(255, 255, 255);"><br></div=
><div style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slat=
e Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initia=
l; background-color: rgb(255, 255, 255);"><span style=3D"line-height: initi=
al;">inline currently does nothing, besides prevent ODR violations. </span>=
</div><div style=3D"width: 100%; font-size: initial; font-family: Calibri, =
'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: i=
nitial; background-color: rgb(255, 255, 255);"><br></div><div style=3D"widt=
h: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif,=
 sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color=
: rgb(255, 255, 255);">Having said all that, you propose an attribute [[for=
ce_inline]]. It would be an attribute because those have no guaranteed mean=
ing and are ignorable by the compiler. Exactly like inline! would be.</div>=
<div style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate=
 Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial=
; background-color: rgb(255, 255, 255);"><br></div>                        =
                                                                           =
                                  <div style=3D"width: 100%; font-size: ini=
tial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb=
(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">=
<br style=3D"display:initial"></div>                                       =
                                                                           =
                                                                           =
      <div style=3D"font-size: initial; font-family: Calibri, 'Slate Pro', =
sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backg=
round-color: rgb(255, 255, 255);">Sent&nbsp;from&nbsp;my&nbsp;BlackBerry&nb=
sp;portable&nbsp;Babbage&nbsp;Device</div>                                 =
                                                                           =
                                                                      <tabl=
e width=3D"100%" style=3D"background-color:white;border-spacing:0px;"> <tbo=
dy><tr><td colspan=3D"2" style=3D"font-size: initial; text-align: initial; =
background-color: rgb(255, 255, 255);">                           <div styl=
e=3D"border-style: solid none none; border-top-color: rgb(181, 196, 223); b=
order-top-width: 1pt; padding: 3pt 0in 0in; font-family: Tahoma, 'BB Alpha =
Sans', 'Slate Pro'; font-size: 10pt;">  <div><b>From: </b>gmisocpp@gmail.co=
m</div><div><b>Sent: </b>Wednesday, July 11, 2018 3:14 AM</div><div><b>To: =
</b>ISO C++ Standard - Future Proposals</div><div><b>Reply To: </b>std-prop=
osals@isocpp.org</div><div><b>Subject: </b>Re: [std-proposals] constexpr! o=
r constexpr(false)?</div></div></td></tr></tbody></table><div style=3D"bord=
er-style: solid none none; border-top-color: rgb(186, 188, 209); border-top=
-width: 1pt; font-size: initial; text-align: initial; background-color: rgb=
(255, 255, 255);"></div><br><div id=3D"_originalContent" style=3D""><div di=
r=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 4:54:15 PM UTC+12, Nicol B=
olas wrote:<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-left-style: solid;"><div dir=3D"ltr">On Tuesday, July 1=
0, 2018 at 11:20:53 PM UTC-4, <a>gmis...@gmail.com</a> wrote:<blockquote cl=
ass=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-left-=
style: solid;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"=
margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 2=
04, 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote"><div><br></div><div>I don't think we can=
 standardize anything to replace __forceinline.</div><div>It has no meaning=
 to the abstract machine.<br></div><div>The "as-if" rule means you can't te=
ll (by running the code) whether it was inlined.</div><div>For example, wha=
t if my implementation is an interpreter, not a compiler? What does inline =
mean then?<br></div><br clear=3D"all"></div><br>-- <br><div><div dir=3D"ltr=
"><div>Be seeing you,<br></div>Tony<br></div></div></div></div></blockquote=
><div><br></div><div>I don't understand the problem.</div><div>But&nbsp;do =
we have to&nbsp;specify what it means in any detail?</div></div></blockquot=
e><div><br></div><div>Because that's what a specification is: specifying be=
havior in sufficient detail.<br></div></div></blockquote><div><br></div><di=
v>Sounds patronising.</div><div>There are plenty of things that are in C++ =
that are specified as unspecified or implementation defined etc. But it's i=
rrelevant to what I actually suggested anyway.</div><div>&nbsp;</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-lef=
t: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; bord=
er-left-style: solid;"><div dir=3D"ltr"><div></div><div><br></div><blockquo=
te 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-=
left-style: solid;"><div dir=3D"ltr"><div>What's wrong with inline! meaning=
&nbsp;"if you can inline this function by any means, do so. If it really ca=
n't be forced inline act as inline".</div></div></blockquote><div><br></div=
><div>Because then you have to define what it means to "inline a function" =
and how that relates to the abstract machine.<br></div></div></blockquote><=
div><br></div><div>We know what it means to inline a function, it's called =
inline.</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204=
, 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"=
><div></div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204,=
 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr">=
<div>I would expect&nbsp;compilers&nbsp;issue a warning and behave in whate=
ver way inline would have.</div><div><br></div><div>Why would this stop an =
interpreter?</div></div></blockquote><div><br></div><div>Because the concep=
t of "inline a function" is primarily built around code generation. A funct=
ion is inlined by generating its code at each call site.</div><div><br></di=
v><div>In an interpreter, there is no code generation. You just have a post=
-compiled AST, which your interpreter walks through. "Inlining" has no mean=
ing here, but the C++ abstract machine still does.<br></div></div></blockqu=
ote><div><br></div><div>inline is already in the standard, so again why is =
inline! as&nbsp;a try harder to inline directive that resorts to inline&nbs=
p;if it can't, an impossible thing when we already have inline and many imp=
lementations have __forceinline or always_inline etc.?</div><div>If&nbsp;in=
terpreter or non interpreter&nbsp;"can't" it'd do what inline does.</div><d=
iv><br></div><div>Where's the problem?</div><div><br></div><div><br></div><=
/div>

<p></p>

-- <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"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a8f4b2c0-d025-4973-98d7-6a60b8071068%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/a8f4b2c0-d025-4973-98d7-6a60b807=
1068%40isocpp.org</a>.<br>
<br><!--end of _originalContent --></div></body></html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20180711072840.5177422.61062.57260%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20180711072840.5177422.61062.57260%40gm=
ail.com</a>.<br />

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jul 2018 00:59:07 -0700 (PDT)
Raw View
------=_Part_67829_1444757772.1531295947097
Content-Type: multipart/alternative;
 boundary="----=_Part_67830_585645855.1531295947097"

------=_Part_67830_585645855.1531295947097
Content-Type: text/plain; charset="UTF-8"



On Wednesday, July 11, 2018 at 7:28:43 PM UTC+12, Tony V E wrote:
>
> If inline! is allowed to fall back to inline, than inline! would be no
> better than inline.
> Because that's what the current inline already does: inline if you can (or
> 'want').
>

Yes. That's what I expect, inline is the fall-back option. What's the
problem with that?


>
>
> You can say there's a difference between 'can' and 'want', but there
> isn't. Compilers are always free to do things if you can write code that
> detects what it did and prints out the difference. The 'as-if' rule.
>
> And what does inline *really* mean currently? It doesn't mean inline the
> code, it means don't complain about multiple definitions of the same
> function. That's why we recently decided to use it on variables.
>

It doesn't matter what inline does. It's the fall back option. It's there
and that's all it has to be. I don't think we need to know what it means as
I said to Nicol.


> inline currently does nothing, besides prevent ODR violations.
>
> Having said all that, you propose an attribute [[force_inline]]. It would
> be an attribute because those have no guaranteed meaning and are ignorable
> by the compiler. Exactly like inline! would be.
>

I would accept an attribute (I guess), but I don't think it follows through
that it has to be an attribute just because it might get ignored.
My argument was that consistency-wise, it has some kind of similarity with
constexpr! where ! means 'I really want it'.

I think the compiler should probably issue a warning if it can't so you
know you have something to address.
I don't know if tagging something with an attributes then warning on it is
supposed to be acceptable. But using ! seems cleaner and more consistent
with constexpr use and ! is used for emphasis so it's teachable as 'try
really hard to inline this!', it seems ok to me.

Having said all that, I wouldn't mind if it was an attribute either, rather
than giving up and saying this is impossible or all too hard.

People have implemented __forceinline and  always_inline and inline so I
don't think it would be so hard for the committee to pass some improvement
in this area.
Currently we are using macros to pick the __forceinline or always_inline
and based on compiler - see libcxx's __config for an example.
This requires using the pre-processor which we are saying we'd like to
reduce dependence on.

This suggestion would rid some of that code.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/73b413ed-cfef-4174-ac91-51f1eff0274d%40isocpp.org.

------=_Part_67830_585645855.1531295947097
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 7:28:43 PM UTC+12, =
Tony V E wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-=
left-width: 1px; border-left-style: solid;"><div lang=3D"en-US" style=3D"ba=
ckground-color: rgb(255, 255, 255);">                                      =
                                                <div style=3D"width: 100%; =
color: rgb(31, 73, 125); font-family: Calibri,&quot;Slate Pro&quot;,sans-se=
rif,sans-serif; background-color: rgb(255, 255, 255);">If inline! is allowe=
d to fall back to inline, than inline! would be no better than inline.</div=
><div style=3D"width: 100%; color: rgb(31, 73, 125); font-family: Calibri,&=
quot;Slate Pro&quot;,sans-serif,sans-serif; background-color: rgb(255, 255,=
 255);">Because that&#39;s what the current inline already does: inline if =
you can (or &#39;want&#39;).</div></div></blockquote><div><br></div><div>Ye=
s. That&#39;s what I expect,=C2=A0inline is the=C2=A0fall-back option. What=
&#39;s=C2=A0the problem with that? </div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bor=
der-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-sty=
le: solid;"><div lang=3D"en-US" style=3D"background-color: rgb(255, 255, 25=
5);"><div style=3D"width: 100%; color: rgb(31, 73, 125); font-family: Calib=
ri,&quot;Slate Pro&quot;,sans-serif,sans-serif; background-color: rgb(255, =
255, 255);"><br></div><div style=3D"width: 100%; color: rgb(31, 73, 125); f=
ont-family: Calibri,&quot;Slate Pro&quot;,sans-serif,sans-serif; background=
-color: rgb(255, 255, 255);"><span><br></span></div><div style=3D"width: 10=
0%; color: rgb(31, 73, 125); font-family: Calibri,&quot;Slate Pro&quot;,san=
s-serif,sans-serif; background-color: rgb(255, 255, 255);"><span>You can sa=
y there&#39;s a difference between &#39;can&#39; and &#39;want&#39;, but th=
ere isn&#39;t. Compilers are always free to do things if you can write code=
 that detects what it did and prints out the difference. The &#39;as-if&#39=
; rule.</span></div><div style=3D"width: 100%; color: rgb(31, 73, 125); fon=
t-family: Calibri,&quot;Slate Pro&quot;,sans-serif,sans-serif; background-c=
olor: rgb(255, 255, 255);"><br></div><div style=3D"width: 100%; color: rgb(=
31, 73, 125); font-family: Calibri,&quot;Slate Pro&quot;,sans-serif,sans-se=
rif; background-color: rgb(255, 255, 255);">And what does inline *really* m=
ean currently? It doesn&#39;t mean inline the code, it means don&#39;t comp=
lain about multiple definitions of the same function. That&#39;s why we rec=
ently decided to use it on variables. </div></div></blockquote><div><br></d=
iv><div>It doesn&#39;t matter=C2=A0what inline does. It&#39;s the fall back=
 option.=C2=A0It&#39;s there and that&#39;s all it has to be. I don&#39;t t=
hink we need to know what it means as I said to Nicol.</div><div><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; paddi=
ng-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px=
; border-left-style: solid;"><div lang=3D"en-US" style=3D"background-color:=
 rgb(255, 255, 255);"><div style=3D"width: 100%; color: rgb(31, 73, 125); f=
ont-family: Calibri,&quot;Slate Pro&quot;,sans-serif,sans-serif; background=
-color: rgb(255, 255, 255);"><br></div><div style=3D"width: 100%; color: rg=
b(31, 73, 125); font-family: Calibri,&quot;Slate Pro&quot;,sans-serif,sans-=
serif; background-color: rgb(255, 255, 255);"><span>inline currently does n=
othing, besides prevent ODR violations. </span></div><div style=3D"width: 1=
00%; color: rgb(31, 73, 125); font-family: Calibri,&quot;Slate Pro&quot;,sa=
ns-serif,sans-serif; background-color: rgb(255, 255, 255);"><br></div><div =
style=3D"width: 100%; color: rgb(31, 73, 125); font-family: Calibri,&quot;S=
late Pro&quot;,sans-serif,sans-serif; background-color: rgb(255, 255, 255);=
">Having said all that, you propose an attribute [[force_inline]]. It would=
 be an attribute because those have no guaranteed meaning and are ignorable=
 by the compiler. Exactly like inline! would be.</div></div></blockquote><d=
iv><br></div><div>I would accept an attribute (I guess), but I don&#39;t th=
ink it follows through that it has to be an attribute just because it might=
 get ignored.</div><div>My argument was that consistency-wise, it has some =
kind of similarity with constexpr! where ! means &#39;I really want it&#39;=
..</div><div><br></div><div>I think the=C2=A0compiler=C2=A0should probably i=
ssue a=C2=A0warning if it can&#39;t so=C2=A0you know you have something to =
address.</div><div>I don&#39;t know if=C2=A0tagging something with an=C2=A0=
attributes then warning on it=C2=A0is supposed to be acceptable. But using =
! seems cleaner and more consistent with constexpr use and ! is used for em=
phasis=C2=A0so it&#39;s teachable as=C2=A0&#39;try really hard to inline th=
is!&#39;, it=C2=A0seems ok to me.</div><div><br></div><div>Having said all =
that, I wouldn&#39;t mind if it was an attribute either, rather than giving=
 up and saying this is impossible or all too hard.</div><div><br></div><div=
>People have implemented __forceinline and=C2=A0 always_inline and inline s=
o I don&#39;t think it would be so hard for the committee to pass some impr=
ovement in this area.</div><div>Currently we are using macros to pick the _=
_forceinline or always_inline and based on compiler - see libcxx&#39;s __co=
nfig for an example.</div><div>This requires using the pre-processor which =
we are saying we&#39;d like to reduce dependence on.</div><div><br></div><d=
iv>This suggestion would rid some of that code.</div><div><br></div>
</div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/73b413ed-cfef-4174-ac91-51f1eff0274d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/73b413ed-cfef-4174-ac91-51f1eff0274d=
%40isocpp.org</a>.<br />

------=_Part_67830_585645855.1531295947097--

------=_Part_67829_1444757772.1531295947097--

.


Author: florian.csdt@gmail.com
Date: Wed, 11 Jul 2018 01:23:51 -0700 (PDT)
Raw View
------=_Part_100006_697447855.1531297431377
Content-Type: multipart/alternative;
 boundary="----=_Part_100007_192318938.1531297431378"

------=_Part_100007_192318938.1531297431378
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mercredi 11 juillet 2018 09:59:07 UTC+2, gmis...@gmail.com a =C3=A9crit =
:
>
>
>
> On Wednesday, July 11, 2018 at 7:28:43 PM UTC+12, Tony V E wrote:
>>
>> If inline! is allowed to fall back to inline, than inline! would be no=
=20
>> better than inline.
>> Because that's what the current inline already does: inline if you can=
=20
>> (or 'want').
>>
>
> Yes. That's what I expect, inline is the fall-back option. What's the=20
> problem with that?=20
> =20
>
>>
>>
>> You can say there's a difference between 'can' and 'want', but there=20
>> isn't. Compilers are always free to do things if you can write code that=
=20
>> detects what it did and prints out the difference. The 'as-if' rule.
>>
>> And what does inline *really* mean currently? It doesn't mean inline the=
=20
>> code, it means don't complain about multiple definitions of the same=20
>> function. That's why we recently decided to use it on variables.=20
>>
>
> It doesn't matter what inline does. It's the fall back option. It's there=
=20
> and that's all it has to be. I don't think we need to know what it means =
as=20
> I said to Nicol.
>
>
>> inline currently does nothing, besides prevent ODR violations.=20
>>
>> Having said all that, you propose an attribute [[force_inline]]. It woul=
d=20
>> be an attribute because those have no guaranteed meaning and are ignorab=
le=20
>> by the compiler. Exactly like inline! would be.
>>
>
> I would accept an attribute (I guess), but I don't think it follows=20
> through that it has to be an attribute just because it might get ignored.
> My argument was that consistency-wise, it has some kind of similarity wit=
h=20
> constexpr! where ! means 'I really want it'.
>
> I think the compiler should probably issue a warning if it can't so you=
=20
> know you have something to address.
> I don't know if tagging something with an attributes then warning on it i=
s=20
> supposed to be acceptable. But using ! seems cleaner and more consistent=
=20
> with constexpr use and ! is used for emphasis so it's teachable as 'try=
=20
> really hard to inline this!', it seems ok to me.
>
> Having said all that, I wouldn't mind if it was an attribute either,=20
> rather than giving up and saying this is impossible or all too hard.
>
> People have implemented __forceinline and  always_inline and inline so I=
=20
> don't think it would be so hard for the committee to pass some improvemen=
t=20
> in this area.
> Currently we are using macros to pick the __forceinline or always_inline=
=20
> and based on compiler - see libcxx's __config for an example.
> This requires using the pre-processor which we are saying we'd like to=20
> reduce dependence on.
>
> This suggestion would rid some of that code.
>
>

I would like to highlight some facts: the inline keyword is not about=20
inlining. As already said by others, the abstract machine has no notion of=
=20
what is inlining.
The reason is simple: inlining doesn't change the behavior of a program,=20
only its speed (and stack usage in some cases).
The abstract machine doesn't care about speed, only the bahavior.

Currently, what inline is about is multiple definition of a single=20
function/object across translation units.
If you want extra information, have a look at=20
https://en.cppreference.com/w/cpp/language/inline

That being said, it would still be interested to have a force inline.
The best example I can think of is calling alloca within a function, and=20
returning the pointer. On every compilers I tested, the allocated stack=20
memory is kept after this call iif the call is actually inlined.
One use case would be runtime size class:
template class T>
class stack_array {
  private:
    T* p;
  public:
    inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
    stack_array() =3D delete;
    stack_array(const stack_array&) =3D delete;
    stack_array& operator=3D(const stack_array&) =3D delete;
    ~stack_array() =3D default;

    /* ... */
};

Now, to standardize that kind of stuff, I think we should speak in terms of=
=20
scopes:
the internal scope of an inline! function is the same as the scope where=20
the call is performed.
As the alloca memory is "deallocated" at the end of the scope, we have the=
=20
expected behavior.

For this to work, the definition of the inline! function must be visible at=
=20
the call site, and the simplest way to implement it in the compiler is to=
=20
actually perform inlining.
With such a definition, inline! cannot be implemented with an attribute as=
=20
it changes the semantic of the program, and cannot be ignored.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/de2e2db8-03b3-464b-b9d6-f31bba3a1228%40isocpp.or=
g.

------=_Part_100007_192318938.1531297431378
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 09:59:07 UTC+2, gmis..=
..@gmail.com a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 7:28:43 PM UTC+12,=
 Tony V E wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-wi=
dth:1px;border-left-style:solid"><div style=3D"background-color:rgb(255,255=
,255)" lang=3D"en-US">                                                     =
                                 <div style=3D"width:100%;color:rgb(31,73,1=
25);font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sans-serif;backgro=
und-color:rgb(255,255,255)">If inline! is allowed to fall back to inline, t=
han inline! would be no better than inline.</div><div style=3D"width:100%;c=
olor:rgb(31,73,125);font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sa=
ns-serif;background-color:rgb(255,255,255)">Because that&#39;s what the cur=
rent inline already does: inline if you can (or &#39;want&#39;).</div></div=
></blockquote><div><br></div><div>Yes. That&#39;s what I expect,=C2=A0inlin=
e is the=C2=A0fall-back option. What&#39;s=C2=A0the problem with that? </di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left=
-width:1px;border-left-style:solid"><div style=3D"background-color:rgb(255,=
255,255)" lang=3D"en-US"><div style=3D"width:100%;color:rgb(31,73,125);font=
-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sans-serif;background-colo=
r:rgb(255,255,255)"><br></div><div style=3D"width:100%;color:rgb(31,73,125)=
;font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sans-serif;background=
-color:rgb(255,255,255)"><span><br></span></div><div style=3D"width:100%;co=
lor:rgb(31,73,125);font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,san=
s-serif;background-color:rgb(255,255,255)"><span>You can say there&#39;s a =
difference between &#39;can&#39; and &#39;want&#39;, but there isn&#39;t. C=
ompilers are always free to do things if you can write code that detects wh=
at it did and prints out the difference. The &#39;as-if&#39; rule.</span></=
div><div style=3D"width:100%;color:rgb(31,73,125);font-family:Calibri,&quot=
;Slate Pro&quot;,sans-serif,sans-serif;background-color:rgb(255,255,255)"><=
br></div><div style=3D"width:100%;color:rgb(31,73,125);font-family:Calibri,=
&quot;Slate Pro&quot;,sans-serif,sans-serif;background-color:rgb(255,255,25=
5)">And what does inline *really* mean currently? It doesn&#39;t mean inlin=
e the code, it means don&#39;t complain about multiple definitions of the s=
ame function. That&#39;s why we recently decided to use it on variables. </=
div></div></blockquote><div><br></div><div>It doesn&#39;t matter=C2=A0what =
inline does. It&#39;s the fall back option.=C2=A0It&#39;s there and that&#3=
9;s all it has to be. I don&#39;t think we need to know what it means as I =
said to Nicol.</div><div><br></div><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-left-style:solid"><div style=3D"backgrou=
nd-color:rgb(255,255,255)" lang=3D"en-US"><div style=3D"width:100%;color:rg=
b(31,73,125);font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sans-seri=
f;background-color:rgb(255,255,255)"><br></div><div style=3D"width:100%;col=
or:rgb(31,73,125);font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sans=
-serif;background-color:rgb(255,255,255)"><span>inline currently does nothi=
ng, besides prevent ODR violations. </span></div><div style=3D"width:100%;c=
olor:rgb(31,73,125);font-family:Calibri,&quot;Slate Pro&quot;,sans-serif,sa=
ns-serif;background-color:rgb(255,255,255)"><br></div><div style=3D"width:1=
00%;color:rgb(31,73,125);font-family:Calibri,&quot;Slate Pro&quot;,sans-ser=
if,sans-serif;background-color:rgb(255,255,255)">Having said all that, you =
propose an attribute [[force_inline]]. It would be an attribute because tho=
se have no guaranteed meaning and are ignorable by the compiler. Exactly li=
ke inline! would be.</div></div></blockquote><div><br></div><div>I would ac=
cept an attribute (I guess), but I don&#39;t think it follows through that =
it has to be an attribute just because it might get ignored.</div><div>My a=
rgument was that consistency-wise, it has some kind of similarity with cons=
texpr! where ! means &#39;I really want it&#39;.</div><div><br></div><div>I=
 think the=C2=A0compiler=C2=A0should probably issue a=C2=A0warning if it ca=
n&#39;t so=C2=A0you know you have something to address.</div><div>I don&#39=
;t know if=C2=A0tagging something with an=C2=A0attributes then warning on i=
t=C2=A0is supposed to be acceptable. But using ! seems cleaner and more con=
sistent with constexpr use and ! is used for emphasis=C2=A0so it&#39;s teac=
hable as=C2=A0&#39;try really hard to inline this!&#39;, it=C2=A0seems ok t=
o me.</div><div><br></div><div>Having said all that, I wouldn&#39;t mind if=
 it was an attribute either, rather than giving up and saying this is impos=
sible or all too hard.</div><div><br></div><div>People have implemented __f=
orceinline and=C2=A0 always_inline and inline so I don&#39;t think it would=
 be so hard for the committee to pass some improvement in this area.</div><=
div>Currently we are using macros to pick the __forceinline or always_inlin=
e and based on compiler - see libcxx&#39;s __config for an example.</div><d=
iv>This requires using the pre-processor which we are saying we&#39;d like =
to reduce dependence on.</div><div><br></div><div>This suggestion would rid=
 some of that code.</div><div><br></div></div></blockquote><div><br></div><=
div><br></div><div>I would like to highlight some facts: the <span style=3D=
"font-family: courier new, monospace;">inline</span> keyword is not about i=
nlining. As already said by others, the abstract machine has no notion of w=
hat is inlining.</div><div>The reason is simple: inlining doesn&#39;t chang=
e the behavior of a program, only its speed (and stack usage in some cases)=
..</div><div>The abstract machine doesn&#39;t care about speed, only the bah=
avior.</div><div><br></div><div>Currently, what <span style=3D"font-family:=
 courier new, monospace;">inline</span> is about is multiple definition of =
a single function/object across translation units.<br></div><div>If you wan=
t extra information, have a look at https://en.cppreference.com/w/cpp/langu=
age/inline</div><div><br></div><div>That being said, it would still be inte=
rested to have a force inline.</div><div>The best example I can think of is=
 calling alloca within a function, and returning the pointer. On every comp=
ilers I tested, the allocated stack memory is kept after this call iif the =
call is actually inlined.</div><div>One use case would be runtime size clas=
s:</div><div><div style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wr=
ap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">template</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">class<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> stack_array </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">private</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> p</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">public</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">inline</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
!</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> stack_ar=
ray</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> n</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> p</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
alloca</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">n </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)))</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 stack_array</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">delete</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 stack_array</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> stack_array</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">delete</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">operator</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D(</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">const</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> stack_array</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&amp;)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">delete</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">~</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">stack_array</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">default</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">/* ... */</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></div></code></div><br>Now, to standardize that kind of stuff, I think =
we should speak in terms of scopes:</div><div>the internal scope of an inli=
ne! function is the same as the scope where the call is performed.</div><di=
v>As the alloca memory is &quot;deallocated&quot; at the end of the scope, =
we have the expected behavior.</div><div><br></div><div>For this to work, t=
he definition of the inline! function must be visible at the call site, and=
 the simplest way to implement it in the compiler is to actually perform in=
lining.</div><div>With such a definition, inline! cannot be implemented wit=
h an attribute as it changes the semantic of the program, and cannot be ign=
ored.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/de2e2db8-03b3-464b-b9d6-f31bba3a1228%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/de2e2db8-03b3-464b-b9d6-f31bba3a1228=
%40isocpp.org</a>.<br />

------=_Part_100007_192318938.1531297431378--

------=_Part_100006_697447855.1531297431377--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Wed, 11 Jul 2018 12:28:03 +0200
Raw View
--Apple-Mail=_15A126F1-A35A-4F63-A636-C58FE1D8870B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"


> On 11 Jul 2018, at 10:23, florian.csdt@gmail.com wrote:
>=20
>=20
>=20
> Le mercredi 11 juillet 2018 09:59:07 UTC+2, gmis...@gmail.com <http://gma=
il.com/> a =C3=A9crit :
>=20
>=20
> On Wednesday, July 11, 2018 at 7:28:43 PM UTC+12, Tony V E wrote:
> If inline! is allowed to fall back to inline, than inline! would be no be=
tter than inline.
> Because that's what the current inline already does: inline if you can (o=
r 'want').
>=20
> Yes. That's what I expect, inline is the fall-back option. What's the pro=
blem with that?=20
> =20
>=20
>=20
> You can say there's a difference between 'can' and 'want', but there isn'=
t. Compilers are always free to do things if you can write code that detect=
s what it did and prints out the difference. The 'as-if' rule.
>=20
> And what does inline *really* mean currently? It doesn't mean inline the =
code, it means don't complain about multiple definitions of the same functi=
on. That's why we recently decided to use it on variables.
>=20
> It doesn't matter what inline does. It's the fall back option. It's there=
 and that's all it has to be. I don't think we need to know what it means a=
s I said to Nicol.
>=20
>=20
> inline currently does nothing, besides prevent ODR violations.=20
>=20
> Having said all that, you propose an attribute [[force_inline]]. It would=
 be an attribute because those have no guaranteed meaning and are ignorable=
 by the compiler. Exactly like inline! would be.
>=20
> I would accept an attribute (I guess), but I don't think it follows throu=
gh that it has to be an attribute just because it might get ignored.
> My argument was that consistency-wise, it has some kind of similarity wit=
h constexpr! where ! means 'I really want it'.
>=20
> I think the compiler should probably issue a warning if it can't so you k=
now you have something to address.
> I don't know if tagging something with an attributes then warning on it i=
s supposed to be acceptable. But using ! seems cleaner and more consistent =
with constexpr use and ! is used for emphasis so it's teachable as 'try rea=
lly hard to inline this!', it seems ok to me.
>=20
> Having said all that, I wouldn't mind if it was an attribute either, rath=
er than giving up and saying this is impossible or all too hard.
>=20
> People have implemented __forceinline and  always_inline and inline so I =
don't think it would be so hard for the committee to pass some improvement =
in this area.
> Currently we are using macros to pick the __forceinline or always_inline =
and based on compiler - see libcxx's __config for an example.
> This requires using the pre-processor which we are saying we'd like to re=
duce dependence on.
>=20
> This suggestion would rid some of that code.
>=20
>=20
>=20
> I would like to highlight some facts: the inline keyword is not about inl=
ining. As already said by others, the abstract machine has no notion of wha=
t is inlining.
> The reason is simple: inlining doesn't change the behavior of a program, =
only its speed (and stack usage in some cases).
> The abstract machine doesn't care about speed, only the bahavior.

I think this point cannot be laboured too hard. The language is an expressi=
on of intent, not implementation. The compiler should be the final arbiter =
of whether code is inlined or not. It is in a much better position to make =
that call.=20

Much of the time, compilers go much further than inlining. They elide code,=
 unroll loops, reorder and so on. We don=E2=80=99t demand language control =
of these optimisations for good reason - they are irrelevant to the logical=
 intent of the program.=20

Code-inlining of functions is in the same class of optimisation.=20

__forceinline is all fine and dandy as a compiler extension (who=E2=80=99s =
use I will always forbid in any codebase I control for the above reason). I=
t has no place in the language at all.


>=20
> Currently, what inline is about is multiple definition of a single functi=
on/object across translation units.
> If you want extra information, have a look at https://en.cppreference.com=
/w/cpp/language/inline <https://en.cppreference.com/w/cpp/language/inline>
>=20
> That being said, it would still be interested to have a force inline.
> The best example I can think of is calling alloca within a function, and =
returning the pointer. On every compilers I tested, the allocated stack mem=
ory is kept after this call iif the call is actually inlined.
> One use case would be runtime size class:
> template class T>
> class stack_array {
>   private:
>     T* p;
>   public:
>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>     stack_array() =3D delete;
>     stack_array(const stack_array&) =3D delete;
>     stack_array& operator=3D(const stack_array&) =3D delete;
>     ~stack_array() =3D default;
>=20
>     /* ... */
> };
>=20
> Now, to standardize that kind of stuff, I think we should speak in terms =
of scopes:
> the internal scope of an inline! function is the same as the scope where =
the call is performed.
> As the alloca memory is "deallocated" at the end of the scope, we have th=
e expected behavior.
>=20
> For this to work, the definition of the inline! function must be visible =
at the call site, and the simplest way to implement it in the compiler is t=
o actually perform inlining.
> With such a definition, inline! cannot be implemented with an attribute a=
s it changes the semantic of the program, and cannot be ignored.
>=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=
 email to std-proposals+unsubscribe@isocpp.org <mailto:std-proposals+unsubs=
cribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org <mailto:std=
-proposals@isocpp.org>.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/de2e2db8-03b3-464b-b9d6-f31bba3a1228%40isocpp.=
org <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/de2e2db8-=
03b3-464b-b9d6-f31bba3a1228%40isocpp.org?utm_medium=3Demail&utm_source=3Dfo=
oter>.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/6781676F-6065-4B28-B82F-664F1FBC75B2%40gmail.com=
..

--Apple-Mail=_15A126F1-A35A-4F63-A636-C58FE1D8870B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 11 Jul 2018, at 1=
0:23, <a href=3D"mailto:florian.csdt@gmail.com" class=3D"">florian.csdt@gma=
il.com</a> wrote:</div><br class=3D"Apple-interchange-newline"><div class=
=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; fo=
nt-style: normal; font-variant-caps: normal; font-weight: normal; letter-sp=
acing: normal; text-align: start; text-indent: 0px; text-transform: none; w=
hite-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" cla=
ss=3D""><br class=3D""><br class=3D"">Le mercredi 11 juillet 2018 09:59:07 =
UTC+2, gmis...@<a href=3D"http://gmail.com/" class=3D"">gmail.com</a><span =
class=3D"Apple-converted-space">&nbsp;</span>a =C3=A9crit&nbsp;:<blockquote=
 class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-widt=
h: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); pa=
dding-left: 1ex;"><div dir=3D"ltr" class=3D""><br class=3D""><br class=3D""=
>On Wednesday, July 11, 2018 at 7:28:43 PM UTC+12, Tony V E wrote:<blockquo=
te 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-=
left-style: solid;"><div lang=3D"en-US" style=3D"background-color: rgb(255,=
 255, 255);" class=3D""><div style=3D"width: 869.4375px; color: rgb(31, 73,=
 125); font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; backgroun=
d-color: rgb(255, 255, 255);" class=3D"">If inline! is allowed to fall back=
 to inline, than inline! would be no better than inline.</div><div style=3D=
"width: 869.4375px; color: rgb(31, 73, 125); font-family: Calibri, 'Slate P=
ro', sans-serif, sans-serif; background-color: rgb(255, 255, 255);" class=
=3D"">Because that's what the current inline already does: inline if you ca=
n (or 'want').</div></div></blockquote><div class=3D""><br class=3D""></div=
><div class=3D"">Yes. That's what I expect,&nbsp;inline is the&nbsp;fall-ba=
ck option. What's&nbsp;the problem with that?<span class=3D"Apple-converted=
-space">&nbsp;</span></div><div class=3D"">&nbsp;</div><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-left-style:=
 solid;"><div lang=3D"en-US" style=3D"background-color: rgb(255, 255, 255);=
" class=3D""><div style=3D"width: 869.4375px; color: rgb(31, 73, 125); font=
-family: Calibri, 'Slate Pro', sans-serif, sans-serif; background-color: rg=
b(255, 255, 255);" class=3D""><br class=3D""></div><div style=3D"width: 869=
..4375px; color: rgb(31, 73, 125); font-family: Calibri, 'Slate Pro', sans-s=
erif, sans-serif; background-color: rgb(255, 255, 255);" class=3D""><span c=
lass=3D""><br class=3D""></span></div><div style=3D"width: 869.4375px; colo=
r: rgb(31, 73, 125); font-family: Calibri, 'Slate Pro', sans-serif, sans-se=
rif; background-color: rgb(255, 255, 255);" class=3D""><span class=3D"">You=
 can say there's a difference between 'can' and 'want', but there isn't. Co=
mpilers are always free to do things if you can write code that detects wha=
t it did and prints out the difference. The 'as-if' rule.</span></div><div =
style=3D"width: 869.4375px; color: rgb(31, 73, 125); font-family: Calibri, =
'Slate Pro', sans-serif, sans-serif; background-color: rgb(255, 255, 255);"=
 class=3D""><br class=3D""></div><div style=3D"width: 869.4375px; color: rg=
b(31, 73, 125); font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; =
background-color: rgb(255, 255, 255);" class=3D"">And what does inline *rea=
lly* mean currently? It doesn't mean inline the code, it means don't compla=
in about multiple definitions of the same function. That's why we recently =
decided to use it on variables.</div></div></blockquote><div class=3D""><br=
 class=3D""></div><div class=3D"">It doesn't matter&nbsp;what inline does. =
It's the fall back option.&nbsp;It's there and that's all it has to be. I d=
on't think we need to know what it means as I said to Nicol.</div><div clas=
s=3D""><br class=3D""></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, =
204); border-left-width: 1px; border-left-style: solid;"><div lang=3D"en-US=
" style=3D"background-color: rgb(255, 255, 255);" class=3D""><div style=3D"=
width: 869.4375px; color: rgb(31, 73, 125); font-family: Calibri, 'Slate Pr=
o', sans-serif, sans-serif; background-color: rgb(255, 255, 255);" class=3D=
""><br class=3D""></div><div style=3D"width: 869.4375px; color: rgb(31, 73,=
 125); font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; backgroun=
d-color: rgb(255, 255, 255);" class=3D""><span class=3D"">inline currently =
does nothing, besides prevent ODR violations.<span class=3D"Apple-converted=
-space">&nbsp;</span></span></div><div style=3D"width: 869.4375px; color: r=
gb(31, 73, 125); font-family: Calibri, 'Slate Pro', sans-serif, sans-serif;=
 background-color: rgb(255, 255, 255);" class=3D""><br class=3D""></div><di=
v style=3D"width: 869.4375px; color: rgb(31, 73, 125); font-family: Calibri=
, 'Slate Pro', sans-serif, sans-serif; background-color: rgb(255, 255, 255)=
;" class=3D"">Having said all that, you propose an attribute [[force_inline=
]]. It would be an attribute because those have no guaranteed meaning and a=
re ignorable by the compiler. Exactly like inline! would be.</div></div></b=
lockquote><div class=3D""><br class=3D""></div><div class=3D"">I would acce=
pt an attribute (I guess), but I don't think it follows through that it has=
 to be an attribute just because it might get ignored.</div><div class=3D""=
>My argument was that consistency-wise, it has some kind of similarity with=
 constexpr! where ! means 'I really want it'.</div><div class=3D""><br clas=
s=3D""></div><div class=3D"">I think the&nbsp;compiler&nbsp;should probably=
 issue a&nbsp;warning if it can't so&nbsp;you know you have something to ad=
dress.</div><div class=3D"">I don't know if&nbsp;tagging something with an&=
nbsp;attributes then warning on it&nbsp;is supposed to be acceptable. But u=
sing ! seems cleaner and more consistent with constexpr use and ! is used f=
or emphasis&nbsp;so it's teachable as&nbsp;'try really hard to inline this!=
', it&nbsp;seems ok to me.</div><div class=3D""><br class=3D""></div><div c=
lass=3D"">Having said all that, I wouldn't mind if it was an attribute eith=
er, rather than giving up and saying this is impossible or all too hard.</d=
iv><div class=3D""><br class=3D""></div><div class=3D"">People have impleme=
nted __forceinline and&nbsp; always_inline and inline so I don't think it w=
ould be so hard for the committee to pass some improvement in this area.</d=
iv><div class=3D"">Currently we are using macros to pick the __forceinline =
or always_inline and based on compiler - see libcxx's __config for an examp=
le.</div><div class=3D"">This requires using the pre-processor which we are=
 saying we'd like to reduce dependence on.</div><div class=3D""><br class=
=3D""></div><div class=3D"">This suggestion would rid some of that code.</d=
iv><div class=3D""><br class=3D""></div></div></blockquote><div class=3D"">=
<br class=3D""></div><div class=3D""><br class=3D""></div><div class=3D"">I=
 would like to highlight some facts: the<span class=3D"Apple-converted-spac=
e">&nbsp;</span><span style=3D"font-family: 'courier new', monospace;" clas=
s=3D"">inline</span><span class=3D"Apple-converted-space">&nbsp;</span>keyw=
ord is not about inlining. As already said by others, the abstract machine =
has no notion of what is inlining.</div><div class=3D"">The reason is simpl=
e: inlining doesn't change the behavior of a program, only its speed (and s=
tack usage in some cases).</div><div class=3D"">The abstract machine doesn'=
t care about speed, only the bahavior.</div></div></div></blockquote><div><=
br class=3D""></div><div>I think this point cannot be laboured too hard. Th=
e <u class=3D"">language</u> is an expression of <u class=3D"">intent</u>, =
not implementation. The compiler should be the final arbiter of whether cod=
e is inlined or not. It is in a much better position to make that call.&nbs=
p;</div><div><br class=3D""></div><div>Much of the time, compilers go much =
further than inlining. They elide code, unroll loops, reorder and so on. We=
 don=E2=80=99t demand language control of these optimisations for good reas=
on - they are irrelevant to the logical intent of the program.&nbsp;</div><=
div><br class=3D""></div><div>Code-inlining of functions is in the same cla=
ss of optimisation.&nbsp;</div><div><br class=3D""></div><div>__forceinline=
 is all fine and dandy as a compiler extension (who=E2=80=99s use I will al=
ways forbid in any codebase I control for the above reason). It has no plac=
e in the <u class=3D"">language</u> at all.</div><div><br class=3D""></div>=
<br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div di=
r=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; font-style: nor=
mal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal=
; text-align: start; text-indent: 0px; text-transform: none; white-space: n=
ormal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><div =
class=3D""><br class=3D""></div><div class=3D"">Currently, what<span class=
=3D"Apple-converted-space">&nbsp;</span><span style=3D"font-family: 'courie=
r new', monospace;" class=3D"">inline</span><span class=3D"Apple-converted-=
space">&nbsp;</span>is about is multiple definition of a single function/ob=
ject across translation units.<br class=3D""></div><div class=3D"">If you w=
ant extra information, have a look at<span class=3D"Apple-converted-space">=
&nbsp;</span><a href=3D"https://en.cppreference.com/w/cpp/language/inline" =
class=3D"">https://en.cppreference.com/w/cpp/language/inline</a></div><div =
class=3D""><br class=3D""></div><div class=3D"">That being said, it would s=
till be interested to have a force inline.</div><div class=3D"">The best ex=
ample I can think of is calling alloca within a function, and returning the=
 pointer. On every compilers I tested, the allocated stack memory is kept a=
fter this call iif the call is actually inlined.</div><div class=3D"">One u=
se case would be runtime size class:</div><div class=3D""><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid =
rgb(187, 187, 187); overflow-wrap: break-word;"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"=
color: rgb(0, 0, 136);">template</span><span class=3D"styled-by-prettify" s=
tyle=3D""><span class=3D"Apple-converted-space">&nbsp;</span></span><span c=
lass=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">class</span><s=
pan class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-=
space">&nbsp;</span>T</span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(102, 102, 0);">&gt;</span><span class=3D"styled-by-prettify" style=
=3D""><br class=3D""></span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(0, 0, 136);">class</span><span class=3D"styled-by-prettify" style=
=3D""><span class=3D"Apple-converted-space">&nbsp;</span>stack_array<span c=
lass=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(102, 102, 0);">{</span><span class=3D"styled=
-by-prettify" style=3D""><br class=3D"">&nbsp;<span class=3D"Apple-converte=
d-space">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"co=
lor: rgb(0, 0, 136);">private</span><span class=3D"styled-by-prettify" styl=
e=3D"color: rgb(102, 102, 0);">:</span><span class=3D"styled-by-prettify" s=
tyle=3D""><br class=3D"">&nbsp; &nbsp; T</span><span class=3D"styled-by-pre=
ttify" style=3D"color: rgb(102, 102, 0);">*</span><span class=3D"styled-by-=
prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</span>p</=
span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">=
;</span><span class=3D"styled-by-prettify" style=3D""><br class=3D"">&nbsp;=
<span class=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(0, 0, 136);">public</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">:</span><span cl=
ass=3D"styled-by-prettify" style=3D""><br class=3D"">&nbsp; &nbsp;<span cla=
ss=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-by-p=
rettify" style=3D"color: rgb(0, 0, 136);">inline</span><span class=3D"style=
d-by-prettify" style=3D"color: rgb(102, 102, 0);">!</span><span class=3D"st=
yled-by-prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</=
span>stack_array</span><span class=3D"styled-by-prettify" style=3D"color: r=
gb(102, 102, 0);">(</span><span class=3D"styled-by-prettify" style=3D"color=
: rgb(0, 0, 136);">int</span><span class=3D"styled-by-prettify" style=3D"">=
<span class=3D"Apple-converted-space">&nbsp;</span>n</span><span class=3D"s=
tyled-by-prettify" style=3D"color: rgb(102, 102, 0);">)</span><span class=
=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-space">&n=
bsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: rgb(10=
2, 102, 0);">:</span><span class=3D"styled-by-prettify" style=3D""><span cl=
ass=3D"Apple-converted-space">&nbsp;</span>p</span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(102, 102, 0);">(</span><span class=3D"styled=
-by-prettify" style=3D"">alloca</span><span class=3D"styled-by-prettify" st=
yle=3D"color: rgb(102, 102, 0);">(</span><span class=3D"styled-by-prettify"=
 style=3D"">n<span class=3D"Apple-converted-space">&nbsp;</span></span><spa=
n class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">*</span><=
span class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted=
-space">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(0, 0, 136);">sizeof</span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(102, 102, 0);">(</span><span class=3D"styled-by-prettify" st=
yle=3D"">T</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102=
, 102, 0);">)))</span><span class=3D"styled-by-prettify" style=3D""><span c=
lass=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(102, 102, 0);">{}</span><span class=3D"style=
d-by-prettify" style=3D""><br class=3D"">&nbsp; &nbsp; stack_array</span><s=
pan class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">()</spa=
n><span class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-conver=
ted-space">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(102, 102, 0);">=3D</span><span class=3D"styled-by-prettify" styl=
e=3D""><span class=3D"Apple-converted-space">&nbsp;</span></span><span clas=
s=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">delete</span><spa=
n class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><=
span class=3D"styled-by-prettify" style=3D""><br class=3D"">&nbsp; &nbsp; s=
tack_array</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102=
, 102, 0);">(</span><span class=3D"styled-by-prettify" style=3D"color: rgb(=
0, 0, 136);">const</span><span class=3D"styled-by-prettify" style=3D""><spa=
n class=3D"Apple-converted-space">&nbsp;</span>stack_array</span><span clas=
s=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">&amp;)</span><s=
pan class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-=
space">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"colo=
r: rgb(102, 102, 0);">=3D</span><span class=3D"styled-by-prettify" style=3D=
""><span class=3D"Apple-converted-space">&nbsp;</span></span><span class=3D=
"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">delete</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><span=
 class=3D"styled-by-prettify" style=3D""><br class=3D"">&nbsp; &nbsp; stack=
_array</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 10=
2, 0);">&amp;</span><span class=3D"styled-by-prettify" style=3D""><span cla=
ss=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-by-p=
rettify" style=3D"color: rgb(0, 0, 136);">operator</span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(102, 102, 0);">=3D(</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">const</span><span =
class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-spac=
e">&nbsp;</span>stack_array</span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(102, 102, 0);">&amp;)</span><span class=3D"styled-by-prettif=
y" style=3D""><span class=3D"Apple-converted-space">&nbsp;</span></span><sp=
an class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">=3D</spa=
n><span class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-conver=
ted-space">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(0, 0, 136);">delete</span><span class=3D"styled-by-prettify" sty=
le=3D"color: rgb(102, 102, 0);">;</span><span class=3D"styled-by-prettify" =
style=3D""><br class=3D"">&nbsp; &nbsp;<span class=3D"Apple-converted-space=
">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: rg=
b(102, 102, 0);">~</span><span class=3D"styled-by-prettify" style=3D"">stac=
k_array</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 1=
02, 0);">()</span><span class=3D"styled-by-prettify" style=3D""><span class=
=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-by-pre=
ttify" style=3D"color: rgb(102, 102, 0);">=3D</span><span class=3D"styled-b=
y-prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</span><=
/span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">d=
efault</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 10=
2, 0);">;</span><span class=3D"styled-by-prettify" style=3D""><br class=3D"=
"><br class=3D"">&nbsp; &nbsp;<span class=3D"Apple-converted-space">&nbsp;<=
/span></span><span class=3D"styled-by-prettify" style=3D"color: rgb(136, 0,=
 0);">/* ... */</span><span class=3D"styled-by-prettify" style=3D""><br cla=
ss=3D""></span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, =
102, 0);">};</span><span class=3D"styled-by-prettify" style=3D""><br class=
=3D""></span></div></code></div><br class=3D"">Now, to standardize that kin=
d of stuff, I think we should speak in terms of scopes:</div><div class=3D"=
">the internal scope of an inline! function is the same as the scope where =
the call is performed.</div><div class=3D"">As the alloca memory is "deallo=
cated" at the end of the scope, we have the expected behavior.</div><div cl=
ass=3D""><br class=3D""></div><div class=3D"">For this to work, the definit=
ion of the inline! function must be visible at the call site, and the simpl=
est way to implement it in the compiler is to actually perform inlining.</d=
iv><div class=3D"">With such a definition, inline! cannot be implemented wi=
th an attribute as it changes the semantic of the program, and cannot be ig=
nored.<br class=3D""></div></div><div style=3D"font-family: Helvetica; font=
-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: no=
rmal; letter-spacing: normal; text-align: start; text-indent: 0px; text-tra=
nsform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-w=
idth: 0px;" class=3D""><br class=3D"webkit-block-placeholder"></div><span s=
tyle=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font-v=
ariant-caps: normal; font-weight: normal; letter-spacing: normal; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; word=
-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline=
 !important;" class=3D"">--<span class=3D"Apple-converted-space">&nbsp;</sp=
an></span><br style=3D"font-family: Helvetica; font-size: 12px; font-style:=
 normal; font-variant-caps: normal; font-weight: normal; letter-spacing: no=
rmal; text-align: start; text-indent: 0px; text-transform: none; white-spac=
e: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><=
span style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; tex=
t-align: start; text-indent: 0px; text-transform: none; white-space: normal=
; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: =
inline !important;" class=3D"">You received this message because you are su=
bscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<=
/span><br style=3D"font-family: Helvetica; font-size: 12px; font-style: nor=
mal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal=
; text-align: start; text-indent: 0px; text-transform: none; white-space: n=
ormal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><span=
 style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font=
-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-al=
ign: start; text-indent: 0px; text-transform: none; white-space: normal; wo=
rd-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inli=
ne !important;" class=3D"">To unsubscribe from this group and stop receivin=
g emails from it, send an email to<span class=3D"Apple-converted-space">&nb=
sp;</span></span><a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" st=
yle=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font-va=
riant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: a=
uto; text-align: start; text-indent: 0px; text-transform: none; white-space=
: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; =
-webkit-text-stroke-width: 0px;" class=3D"">std-proposals+unsubscribe@isocp=
p.org</a><span style=3D"font-family: Helvetica; font-size: 12px; font-style=
: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: n=
ormal; text-align: start; text-indent: 0px; text-transform: none; white-spa=
ce: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none;=
 display: inline !important;" class=3D"">.</span><br style=3D"font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; =
font-weight: normal; letter-spacing: normal; text-align: start; text-indent=
: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webki=
t-text-stroke-width: 0px;" class=3D""><span style=3D"font-family: Helvetica=
; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weig=
ht: normal; letter-spacing: normal; text-align: start; text-indent: 0px; te=
xt-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-st=
roke-width: 0px; float: none; display: inline !important;" class=3D"">To po=
st to this group, send email to<span class=3D"Apple-converted-space">&nbsp;=
</span></span><a href=3D"mailto:std-proposals@isocpp.org" style=3D"font-fam=
ily: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: nor=
mal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align=
: start; text-indent: 0px; text-transform: none; white-space: normal; widow=
s: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-st=
roke-width: 0px;" class=3D"">std-proposals@isocpp.org</a><span style=3D"fon=
t-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps=
: normal; font-weight: normal; letter-spacing: normal; text-align: start; t=
ext-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0=
px; -webkit-text-stroke-width: 0px; float: none; display: inline !important=
;" class=3D"">.</span><br style=3D"font-family: Helvetica; font-size: 12px;=
 font-style: normal; font-variant-caps: normal; font-weight: normal; letter=
-spacing: normal; text-align: start; text-indent: 0px; text-transform: none=
; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" =
class=3D""><span style=3D"font-family: Helvetica; font-size: 12px; font-sty=
le: normal; font-variant-caps: normal; font-weight: normal; letter-spacing:=
 normal; text-align: start; text-indent: 0px; text-transform: none; white-s=
pace: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: non=
e; display: inline !important;" class=3D"">To view this discussion on the w=
eb visit<span class=3D"Apple-converted-space">&nbsp;</span></span><a href=
=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/de2e2db8-0=
3b3-464b-b9d6-f31bba3a1228%40isocpp.org?utm_medium=3Demail&amp;utm_source=
=3Dfooter" style=3D"font-family: Helvetica; font-size: 12px; font-style: no=
rmal; font-variant-caps: normal; font-weight: normal; letter-spacing: norma=
l; orphans: auto; text-align: start; text-indent: 0px; text-transform: none=
; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-a=
djust: auto; -webkit-text-stroke-width: 0px;" class=3D"">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/de2e2db8-03b3-464b-b9d6-f31bba3a=
1228%40isocpp.org</a><span style=3D"font-family: Helvetica; font-size: 12px=
; font-style: normal; font-variant-caps: normal; font-weight: normal; lette=
r-spacing: normal; text-align: start; text-indent: 0px; text-transform: non=
e; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
float: none; display: inline !important;" class=3D"">.</span></div></blockq=
uote></div><br class=3D""></body></html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/6781676F-6065-4B28-B82F-664F1FBC75B2%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/6781676F-6065-4B28-B82F-664F1FBC75B2%=
40gmail.com</a>.<br />

--Apple-Mail=_15A126F1-A35A-4F63-A636-C58FE1D8870B--

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jul 2018 03:35:12 -0700 (PDT)
Raw View
------=_Part_126378_1131050350.1531305312864
Content-Type: multipart/alternative;
 boundary="----=_Part_126379_310321190.1531305312865"

------=_Part_126379_310321190.1531305312865
Content-Type: text/plain; charset="UTF-8"



On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.com wrote:
>
>
> I would like to highlight some facts: the inline keyword is not about
> inlining. As already said by others, the abstract machine has no notion of
> what is inlining.
> The reason is simple: inlining doesn't change the behavior of a program,
> only its speed (and stack usage in some cases).
> The abstract machine doesn't care about speed, only the bahavior.
>

I'm not sure keep thinking about inline on it's own is helpful to my
case, though perhaps it might be for your case.
But see my comment later.



>
> Currently, what inline is about is multiple definition of a single
> function/object across translation units.
> If you want extra information, have a look at
> https://en.cppreference.com/w/cpp/language/inline
> <https://www.google.com/url?q=https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline&sa=D&sntz=1&usg=AFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw>
>
> That being said, it would still be interested to have a force inline.
> The best example I can think of is calling alloca within a function, and
> returning the pointer. On every compilers I tested, the allocated stack
> memory is kept after this call iif the call is actually inlined.
> One use case would be runtime size class:
> template class T>
> class stack_array {
>   private:
>     T* p;
>   public:
>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>     stack_array() = delete;
>     stack_array(const stack_array&) = delete;
>     stack_array& operator=(const stack_array&) = delete;
>     ~stack_array() = default;
>
>     /* ... */
> };
>
> Now, to standardize that kind of stuff, I think we should speak in terms
> of scopes:
> the internal scope of an inline! function is the same as the scope where
> the call is performed.
> As the alloca memory is "deallocated" at the end of the scope, we have the
> expected behavior.
>
> For this to work, the definition of the inline! function must be visible
> at the call site, and the simplest way to implement it in the compiler is
> to actually perform inlining.
> With such a definition, inline! cannot be implemented with an attribute as
> it changes the semantic of the program, and cannot be ignored.
>

People compile their code and when they don't get the result they want,
they use __forceinline or always_inline or resort to that immediately.
At that point they now have compiler specific code and macros. If they had
inline! in terms in the mentioned they would have less of that type of code.
My description of inline! if defined in terms of __forceinline and
always_inline.

What you are after sounds like something more complicated and therefore
a different feature than what my suggestion is aiming for.
I've little doubt that what you want is of value but you are opening more
cans of worms to get it.
A question to ask also is does your feature likely promise to do the thing
that makes people reach for __forceinline and always_inline.

I don't really have much of a problem with anything you've said other than
I think if everyone heads off to define that what you are talking about I
suspect it'll be something else to what I'm proposing. If it makes C++
better, ok. It seems there are a few features in this space that people
need.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d7201ef1-1e7b-4735-bd84-8e81b3983d10%40isocpp.org.

------=_Part_126379_310321190.1531305312865
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, =
floria...@gmail.com 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"><di=
v><br></div><div>I would like to highlight some facts: the <span style=3D"f=
ont-family: courier new,monospace;">inline</span> keyword is not about inli=
ning. As already said by others, the abstract machine has no notion of what=
 is inlining.</div><div>The reason is simple: inlining doesn&#39;t change t=
he behavior of a program, only its speed (and stack usage in some cases).</=
div><div>The abstract machine doesn&#39;t care about speed, only the bahavi=
or.</div></div></blockquote><div><br></div><div>I&#39;m not sure keep think=
ing about inline on it&#39;s own is helpful to my case,=C2=A0though perhaps=
 it might be for your case.</div><div>But see my comment later.</div><div><=
br></div><div>=C2=A0</div><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"><di=
v><br></div><div>Currently, what <span style=3D"font-family: courier new,mo=
nospace;">inline</span> is about is multiple definition of a single functio=
n/object across translation units.<br></div><div>If you want extra informat=
ion, have a look at <a onmousedown=3D"this.href=3D&#39;https://www.google.c=
om/url?q\x3dhttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline=
\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;=
return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dh=
ttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD\x=
26sntz\x3d1\x26usg\x3dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true;"=
 href=3D"https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2=
Fw%2Fcpp%2Flanguage%2Finline&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNGSULKd=
UyQcwORlrV7uAN6nFcNoCw" target=3D"_blank" rel=3D"nofollow">https://en.cppre=
ference.com/w/<wbr>cpp/language/inline</a></div><div><br></div><div>That be=
ing said, it would still be interested to have a force inline.</div><div>Th=
e best example I can think of is calling alloca within a function, and retu=
rning the pointer. On every compilers I tested, the allocated stack memory =
is kept after this call iif the call is actually inlined.</div><div>One use=
 case would be runtime size class:</div><div><div style=3D"border: 1px soli=
d rgb(187, 187, 187); border-image: none; background-color: rgb(250, 250, 2=
50);"><code><div><span style=3D"color: rgb(0, 0, 136);">template</span><spa=
n style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 13=
6);">class</span><span style=3D"color: rgb(0, 0, 0);"> T</span><span style=
=3D"color: rgb(102, 102, 0);">&gt;</span><span style=3D"color: rgb(0, 0, 0)=
;"><br></span><span style=3D"color: rgb(0, 0, 136);">class</span><span styl=
e=3D"color: rgb(0, 0, 0);"> stack_array </span><span style=3D"color: rgb(10=
2, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span=
><span style=3D"color: rgb(0, 0, 136);">private</span><span style=3D"color:=
 rgb(102, 102, 0);">:</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0=
 =C2=A0 T</span><span style=3D"color: rgb(102, 102, 0);">*</span><span styl=
e=3D"color: rgb(0, 0, 0);"> p</span><span style=3D"color: rgb(102, 102, 0);=
">;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span styl=
e=3D"color: rgb(0, 0, 136);">public</span><span style=3D"color: rgb(102, 10=
2, 0);">:</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: rgb(0, 0, 136);">inline</span><span style=3D"color=
: rgb(102, 102, 0);">!</span><span style=3D"color: rgb(0, 0, 0);"> stack_ar=
ray</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"c=
olor: rgb(0, 0, 136);">int</span><span style=3D"color: rgb(0, 0, 0);"> n</s=
pan><span style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: =
rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">:</span><sp=
an style=3D"color: rgb(0, 0, 0);"> p</span><span style=3D"color: rgb(102, 1=
02, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">alloca</span><span st=
yle=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0)=
;">n </span><span style=3D"color: rgb(102, 102, 0);">*</span><span style=3D=
"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">sizeo=
f</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"col=
or: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">)))</sp=
an><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(1=
02, 102, 0);">{}</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=
=A0 stack_array</span><span style=3D"color: rgb(102, 102, 0);">()</span><sp=
an style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 10=
2, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(0, 0, 136);">delete</span><span style=3D"color: rgb(102, 102=
, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 stack=
_array</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=
=3D"color: rgb(0, 0, 136);">const</span><span style=3D"color: rgb(0, 0, 0);=
"> stack_array</span><span style=3D"color: rgb(102, 102, 0);">&amp;)</span>=
<span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102,=
 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(0, 0, 136);">delete</span><span style=3D"color: rgb(102, 1=
02, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 sta=
ck_array</span><span style=3D"color: rgb(102, 102, 0);">&amp;</span><span s=
tyle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);=
">operator</span><span style=3D"color: rgb(102, 102, 0);">=3D(</span><span =
style=3D"color: rgb(0, 0, 136);">const</span><span style=3D"color: rgb(0, 0=
, 0);"> stack_array</span><span style=3D"color: rgb(102, 102, 0);">&amp;)</=
span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb=
(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><spa=
n style=3D"color: rgb(0, 0, 136);">delete</span><span style=3D"color: rgb(1=
02, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: rgb(102, 102, 0);">~</span><span style=3D"=
color: rgb(0, 0, 0);">stack_array</span><span style=3D"color: rgb(102, 102,=
 0);">()</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"=
color: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> <=
/span><span style=3D"color: rgb(0, 0, 136);">default</span><span style=3D"c=
olor: rgb(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"><br><=
br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(136, 0, 0);">/* ... */</s=
pan><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: r=
gb(102, 102, 0);">};</span><span style=3D"color: rgb(0, 0, 0);"><br></span>=
</div></code></div><br>Now, to standardize that kind of stuff, I think we s=
hould speak in terms of scopes:</div><div>the internal scope of an inline! =
function is the same as the scope where the call is performed.</div><div>As=
 the alloca memory is &quot;deallocated&quot; at the end of the scope, we h=
ave the expected behavior.</div><div><br></div><div>For this to work, the d=
efinition of the inline! function must be visible at the call site, and the=
 simplest way to implement it in the compiler is to actually perform inlini=
ng.</div><div>With such a definition, inline! cannot be implemented with an=
 attribute as it changes the semantic of the program, and cannot be ignored=
..<br></div></div></blockquote><div><br></div><div>People compile their code=
 and when they don&#39;t get the result they want, they use __forceinline o=
r=C2=A0always_inline or resort to that immediately.</div><div>At that point=
 they now have compiler specific code and macros. If they had inline! in te=
rms=C2=A0in the mentioned they would have less of that type of code.</div><=
div>My description of inline! if defined in terms of __forceinline and alwa=
ys_inline.</div><div><br></div><div>What you are after sounds like somethin=
g more complicated and therefore a=C2=A0different feature than what my sugg=
estion is aiming for.</div><div>I&#39;ve little doubt that what you want is=
 of value but you are opening more cans of worms to get it.</div><div>A que=
stion to ask also is does your feature likely promise to do the thing that=
=C2=A0makes people reach for=C2=A0__forceinline and always_inline.</div><di=
v><br></div><div>I don&#39;t really have much of a problem with anything yo=
u&#39;ve said other than I think if everyone heads off to define that what =
you are talking about I suspect it&#39;ll be something else to what I&#39;m=
 proposing.=C2=A0If it makes C++ better, ok. It seems there are a few featu=
res in this space that people need.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d7201ef1-1e7b-4735-bd84-8e81b3983d10%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d7201ef1-1e7b-4735-bd84-8e81b3983d10=
%40isocpp.org</a>.<br />

------=_Part_126379_310321190.1531305312865--

------=_Part_126378_1131050350.1531305312864--

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jul 2018 03:58:25 -0700 (PDT)
Raw View
------=_Part_115342_1733031368.1531306705264
Content-Type: multipart/alternative;
 boundary="----=_Part_115343_965604832.1531306705264"

------=_Part_115343_965604832.1531306705264
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Wednesday, July 11, 2018 at 10:28:07 PM UTC+12, Richard Hodges wrote:
>
>
> I think this point cannot be laboured too hard. The *language* is an=20
> expression of *intent*, not implementation. The compiler should be the=20
> final arbiter of whether code is inlined or not. It is in a much better=
=20
> position to make that call.=20
>
> Much of the time, compilers go much further than inlining. They elide=20
> code, unroll loops, reorder and so on. We don=E2=80=99t demand language c=
ontrol of=20
> these optimisations for good reason - they are irrelevant to the logical=
=20
> intent of the program.=20
>
> Code-inlining of functions is in the same class of optimisation.=20
>
> __forceinline is all fine and dandy as a compiler extension (who=E2=80=99=
s use I=20
> will always forbid in any codebase I control for the above reason). It ha=
s=20
> no place in the *language* at all.
>

=20
Why do people keep reaching for forceinline then if it has no value, such=
=20
as boost?
Different compilers keep implementing it and people keep using it=20
including popular and peer reviewed ones like boost, so clearly some smart=
=20
people are at some odds with your view on the value of the feature.

Perhaps you should submit a pull request to boost to remove it and see what=
=20
they say?
If we really feel __forceinline has no place then perhaps it is=20
a serious suggestion that thought leading libraries like boost should not=
=20
be using it.
It'd be interesting what they would say to it. I'm sure the result would be=
=20
interesting and strengthen your argument if they removed use of it.

I don't doubt it's a problematic feature and area for what it's worth.=20
Hopefully the discussion will lead to something that make this area less=20
problematic.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/937cc275-dccf-40ae-aa30-ec961fe57b67%40isocpp.or=
g.

------=_Part_115343_965604832.1531306705264
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 10:28:07 PM UTC+12,=
 Richard Hodges wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0p=
x 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); =
border-left-width: 1px; border-left-style: solid;"><div style=3D"-ms-word-w=
rap: break-word;"><div><div><br></div><div>I think this point cannot be lab=
oured too hard. The <u>language</u> is an expression of <u>intent</u>, not =
implementation. The compiler should be the final arbiter of whether code is=
 inlined or not. It is in a much better position to make that call.=C2=A0</=
div><div><br></div><div>Much of the time, compilers go much further than in=
lining. They elide code, unroll loops, reorder and so on. We don=E2=80=99t =
demand language control of these optimisations for good reason - they are i=
rrelevant to the logical intent of the program.=C2=A0</div><div><br></div><=
div>Code-inlining of functions is in the same class of optimisation.=C2=A0<=
/div><div><br></div><div>__forceinline is all fine and dandy as a compiler =
extension (who=E2=80=99s use I will always forbid in any codebase I control=
 for the above reason). It has no place in the <u>language</u> at all.</div=
></div></div></blockquote><div><br></div><div>=C2=A0</div><div>Why do peopl=
e keep reaching for=C2=A0forceinline then if it has no value,=C2=A0such as=
=C2=A0boost?</div><div><div>Different compilers keep implementing it and pe=
ople keep using it including=C2=A0popular and peer reviewed ones like boost=
, so clearly some smart people are at some odds with your view on the value=
 of the feature.</div><div><br></div></div><div>Perhaps you should submit a=
 pull request to boost to remove it and see what they say?</div><div><div>I=
f we really feel __forceinline has no place then perhaps it is a=C2=A0serio=
us=C2=A0suggestion that thought leading libraries like boost should not be =
using it.</div><div>It&#39;d be interesting what they would say to it. I&#3=
9;m sure the result would be interesting and strengthen your argument if th=
ey removed use of it.</div><div><br></div><div>I don&#39;t doubt it&#39;s a=
 problematic feature and area for what it&#39;s worth. Hopefully the discus=
sion will lead to something that make=C2=A0this area=C2=A0less problematic.=
<br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/937cc275-dccf-40ae-aa30-ec961fe57b67%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/937cc275-dccf-40ae-aa30-ec961fe57b67=
%40isocpp.org</a>.<br />

------=_Part_115343_965604832.1531306705264--

------=_Part_115342_1733031368.1531306705264--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Wed, 11 Jul 2018 14:36:02 +0200
Raw View
--00000000000002751c0570b87ec5
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 11 Jul 2018 at 12:58, <gmisocpp@gmail.com> wrote:

>
>
> On Wednesday, July 11, 2018 at 10:28:07 PM UTC+12, Richard Hodges wrote:
>>
>>
>> I think this point cannot be laboured too hard. The *language* is an
>> expression of *intent*, not implementation. The compiler should be the
>> final arbiter of whether code is inlined or not. It is in a much better
>> position to make that call.
>>
>> Much of the time, compilers go much further than inlining. They elide
>> code, unroll loops, reorder and so on. We don=E2=80=99t demand language =
control of
>> these optimisations for good reason - they are irrelevant to the logical
>> intent of the program.
>>
>> Code-inlining of functions is in the same class of optimisation.
>>
>> __forceinline is all fine and dandy as a compiler extension (who=E2=80=
=99s use I
>> will always forbid in any codebase I control for the above reason). It h=
as
>> no place in the *language* at all.
>>
>
>
> Why do people keep reaching for forceinline then if it has no value, such
> as boost?
>

Poor education and a misplaced sense of supremacy perhaps? Supporting
ancient compilers, certainly.


> Different compilers keep implementing it and people keep using it
> including popular and peer reviewed ones like boost, so clearly some smar=
t
> people are at some odds with your view on the value of the feature.
>

It was introduced in the bad old days when hand-optimisation had a chance
of beating compiler optimisation. Presumably still there for backwards
compatibility and to help people who are wrong feel good about their
choices.


>
> Perhaps you should submit a pull request to boost to remove it and see
> what they say?
> If we really feel __forceinline has no place then perhaps it is
> a serious suggestion that thought leading libraries like boost should not
> be using it.
>

Agree, for modern compilers. Boost also supports some pretty ancient ones.
Boost already supports this by defining macros to cater for compiler
differences.


> It'd be interesting what they would say to it. I'm sure the result would
> be interesting and strengthen your argument if they removed use of it.
>
> I don't doubt it's a problematic feature and area for what it's worth.
> Hopefully the discussion will lead to something that make this area less
> problematic.
>

It's not problematic, it's merely not useful to hand-craft code any more.

You'll never recover in processor cycles the time you spent writing and
debugging the non-optimisation.

The man-hours are better spent on improving the compiler, because then the
improvement scales rather than being a one-off non-portable,
non-future-proof anomaly.


> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/937cc275-dcc=
f-40ae-aa30-ec961fe57b67%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/937cc275-dc=
cf-40ae-aa30-ec961fe57b67%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hbMPyoWJG%2BZ2Jg%3D_utFY9e1bacQKfg6zjFFhzM=
eKsiiPQ%40mail.gmail.com.

--00000000000002751c0570b87ec5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, 11 Jul 2018 at 12:58, &lt;<a href=3D"mailto:gmisocpp@gmail.com">gmisocpp@=
gmail.com</a>&gt; wrote:<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"><br><br>On Wednesday, July 11, 2018 at 10:28:07 PM UTC+12, Richard=
 Hodges wrote:<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-widt=
h:1px;border-left-style:solid"><div><div><div><br></div><div>I think this p=
oint cannot be laboured too hard. The <u>language</u> is an expression of <=
u>intent</u>, not implementation. The compiler should be the final arbiter =
of whether code is inlined or not. It is in a much better position to make =
that call.=C2=A0</div><div><br></div><div>Much of the time, compilers go mu=
ch further than inlining. They elide code, unroll loops, reorder and so on.=
 We don=E2=80=99t demand language control of these optimisations for good r=
eason - they are irrelevant to the logical intent of the program.=C2=A0</di=
v><div><br></div><div>Code-inlining of functions is in the same class of op=
timisation.=C2=A0</div><div><br></div><div>__forceinline is all fine and da=
ndy as a compiler extension (who=E2=80=99s use I will always forbid in any =
codebase I control for the above reason). It has no place in the <u>languag=
e</u> at all.</div></div></div></blockquote><div><br></div><div>=C2=A0</div=
><div>Why do people keep reaching for=C2=A0forceinline then if it has no va=
lue,=C2=A0such as=C2=A0boost?</div></div></blockquote><div><br></div><div>P=
oor education and a misplaced sense of supremacy perhaps? Supporting ancien=
t compilers, certainly.</div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div><div>Different compilers keep implementing it and p=
eople keep using it including=C2=A0popular and peer reviewed ones like boos=
t, so clearly some smart people are at some odds with your view on the valu=
e of the feature.</div></div></div></blockquote><div><br></div><div>It was =
introduced in the bad old days when hand-optimisation had a chance of beati=
ng compiler optimisation. Presumably still there for backwards compatibilit=
y and to help people who are wrong feel good about their choices.</div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><br>=
</div></div><div>Perhaps you should submit a pull request to boost to remov=
e it and see what they say?</div><div><div>If we really feel __forceinline =
has no place then perhaps it is a=C2=A0serious=C2=A0suggestion that thought=
 leading libraries like boost should not be using it.</div></div></div></bl=
ockquote><div><br></div><div>Agree, for modern compilers. Boost also suppor=
ts some pretty ancient ones. Boost already supports this by defining macros=
 to cater for compiler differences.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><div>It&#39;d be interesting what they =
would say to it. I&#39;m sure the result would be interesting and strengthe=
n your argument if they removed use of it.</div><div><br></div><div>I don&#=
39;t doubt it&#39;s a problematic feature and area for what it&#39;s worth.=
 Hopefully the discussion will lead to something that make=C2=A0this area=
=C2=A0less problematic.<br></div></div></div></blockquote><div><br></div><d=
iv>It&#39;s not problematic, it&#39;s merely not useful to hand-craft code =
any more.=C2=A0</div><div><br></div><div>You&#39;ll never recover in proces=
sor cycles the time you spent writing and debugging the non-optimisation.=
=C2=A0</div><div><br></div><div>The man-hours are better spent on improving=
 the compiler, because then the improvement scales rather than being a one-=
off non-portable, non-future-proof anomaly.</div><div>=C2=A0<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div><div></div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/937cc275-dccf-40ae-aa30-ec961fe57b67%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/937cc275-dccf-=
40ae-aa30-ec961fe57b67%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hbMPyoWJG%2BZ2Jg%3D_utFY9e1bacQ=
Kfg6zjFFhzMeKsiiPQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbMPyoW=
JG%2BZ2Jg%3D_utFY9e1bacQKfg6zjFFhzMeKsiiPQ%40mail.gmail.com</a>.<br />

--00000000000002751c0570b87ec5--

.


Author: florian.csdt@gmail.com
Date: Wed, 11 Jul 2018 06:04:02 -0700 (PDT)
Raw View
------=_Part_127438_1926152162.1531314242523
Content-Type: multipart/alternative;
 boundary="----=_Part_127439_730532058.1531314242523"

------=_Part_127439_730532058.1531314242523
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a =C3=A9crit =
:
>
>
>
> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.com=20
> wrote:
>>
>>
>> I would like to highlight some facts: the inline keyword is not about=20
>> inlining. As already said by others, the abstract machine has no notion =
of=20
>> what is inlining.
>> The reason is simple: inlining doesn't change the behavior of a program,=
=20
>> only its speed (and stack usage in some cases).
>> The abstract machine doesn't care about speed, only the bahavior.
>>
>
> I'm not sure keep thinking about inline on it's own is helpful to my=20
> case, though perhaps it might be for your case.
> But see my comment later.
>
> =20
>
>>
>> Currently, what inline is about is multiple definition of a single=20
>> function/object across translation units.
>> If you want extra information, have a look at=20
>> https://en.cppreference.com/w/cpp/language/inline=20
>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw%2F=
cpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6nF=
cNoCw>
>>
>> That being said, it would still be interested to have a force inline.
>> The best example I can think of is calling alloca within a function, and=
=20
>> returning the pointer. On every compilers I tested, the allocated stack=
=20
>> memory is kept after this call iif the call is actually inlined.
>> One use case would be runtime size class:
>> template class T>
>> class stack_array {
>>   private:
>>     T* p;
>>   public:
>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>     stack_array() =3D delete;
>>     stack_array(const stack_array&) =3D delete;
>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>     ~stack_array() =3D default;
>>
>>     /* ... */
>> };
>>
>> Now, to standardize that kind of stuff, I think we should speak in terms=
=20
>> of scopes:
>> the internal scope of an inline! function is the same as the scope where=
=20
>> the call is performed.
>> As the alloca memory is "deallocated" at the end of the scope, we have=
=20
>> the expected behavior.
>>
>> For this to work, the definition of the inline! function must be visible=
=20
>> at the call site, and the simplest way to implement it in the compiler i=
s=20
>> to actually perform inlining.
>> With such a definition, inline! cannot be implemented with an attribute=
=20
>> as it changes the semantic of the program, and cannot be ignored.
>>
>
> People compile their code and when they don't get the result they want,=
=20
> they use __forceinline or always_inline or resort to that immediately.
> At that point they now have compiler specific code and macros. If they ha=
d=20
> inline! in terms in the mentioned they would have less of that type of co=
de.
> My description of inline! if defined in terms of __forceinline and=20
> always_inline.
>
> What you are after sounds like something more complicated and therefore=
=20
> a different feature than what my suggestion is aiming for.
> I've little doubt that what you want is of value but you are opening more=
=20
> cans of worms to get it.
> A question to ask also is does your feature likely promise to do the thin=
g=20
> that makes people reach for __forceinline and always_inline.
>
> I don't really have much of a problem with anything you've said other tha=
n=20
> I think if everyone heads off to define that what you are talking about I=
=20
> suspect it'll be something else to what I'm proposing. If it makes C++=20
> better, ok. It seems there are a few features in this space that people=
=20
> need.
>

What I'm after is a way to integrate force inlining into the language using=
=20
the terms of the language itself.
Inlining is an optimization, and like any other optimizations, it is=20
outside the language.
You could say mandatory RVO is an exception, but actually, this=20
optimization is expressed within the language itself, and not like an=20
optimization (with prvalues and copy elision).

If you want to integrate an optimization within the language itself, it=20
should makes something possible:
mandatory copy elision allows to return non-copyable, non moveable objects.
In case of forced inlining, it would allow to allocate objects in the=20
caller scope.

So what I propose is actually simpler to standardize than force inlining=20
because it can be expressed much more easily than inlining itself within=20
the language.

Moreover, with the way I expressed it, the simplest implementation would be=
=20
to force inline. (We probably want to disallow recursion on those functions=
)

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/faa625d2-380a-4eff-aa14-e26f20f03d1b%40isocpp.or=
g.

------=_Part_127439_730532058.1531314242523
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis..=
..@gmail.com a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12,=
 <a>floria...@gmail.com</a> wrote:<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-left-style:solid"><div dir=3D"ltr"><div>=
<br></div><div>I would like to highlight some facts: the <span style=3D"fon=
t-family:courier new,monospace">inline</span> keyword is not about inlining=
.. As already said by others, the abstract machine has no notion of what is =
inlining.</div><div>The reason is simple: inlining doesn&#39;t change the b=
ehavior of a program, only its speed (and stack usage in some cases).</div>=
<div>The abstract machine doesn&#39;t care about speed, only the bahavior.<=
/div></div></blockquote><div><br></div><div>I&#39;m not sure keep thinking =
about inline on it&#39;s own is helpful to my case,=C2=A0though perhaps it =
might be for your case.</div><div>But see my comment later.</div><div><br><=
/div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-l=
eft-width:1px;border-left-style:solid"><div dir=3D"ltr"><div><br></div><div=
>Currently, what <span style=3D"font-family:courier new,monospace">inline</=
span> is about is multiple definition of a single function/object across tr=
anslation units.<br></div><div>If you want extra information, have a look a=
t <a href=3D"https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.c=
om%2Fw%2Fcpp%2Flanguage%2Finline&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNGS=
ULKdUyQcwORlrV7uAN6nFcNoCw" rel=3D"nofollow" target=3D"_blank" onmousedown=
=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fen.cppre=
ference.com%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD\x26sntz\x3d1\x26usg\x3=
dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fen.cppreference.com%2=
Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGSULKd=
UyQcwORlrV7uAN6nFcNoCw&#39;;return true;">https://en.cppreference.com/w/<wb=
r>cpp/language/inline</a></div><div><br></div><div>That being said, it woul=
d still be interested to have a force inline.</div><div>The best example I =
can think of is calling alloca within a function, and returning the pointer=
.. On every compilers I tested, the allocated stack memory is kept after thi=
s call iif the call is actually inlined.</div><div>One use case would be ru=
ntime size class:</div><div><div style=3D"border:1px solid rgb(187,187,187)=
;background-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0=
,136)">template</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> T</sp=
an><span style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb=
(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)">class</span><span st=
yle=3D"color:rgb(0,0,0)"> stack_array </span><span style=3D"color:rgb(102,1=
02,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span sty=
le=3D"color:rgb(0,0,136)">private</span><span style=3D"color:rgb(102,102,0)=
">:</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 T</span><span =
style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> p<=
/span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb=
(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">public</span>=
<span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0=
)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">inline</span=
><span style=3D"color:rgb(102,102,0)">!</span><span style=3D"color:rgb(0,0,=
0)"> stack_array</span><span style=3D"color:rgb(102,102,0)">(</span><span s=
tyle=3D"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> n</=
span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(=
0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D=
"color:rgb(0,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">(</span><s=
pan style=3D"color:rgb(0,0,0)">alloca</span><span style=3D"color:rgb(102,10=
2,0)">(</span><span style=3D"color:rgb(0,0,0)">n </span><span style=3D"colo=
r:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(0,0,136)">sizeof</span><span style=3D"color:rgb(102,102,0)=
">(</span><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:rgb=
(102,102,0)">)))</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">{}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 stack_array</span><span style=3D"color:rgb(102,102,0)">()</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0=
)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,0,136)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><sp=
an style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">cons=
t</span><span style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"=
color:rgb(102,102,0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span=
><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,=
0,0)"> </span><span style=3D"color:rgb(0,0,136)">delete</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 stack_array</span><span style=3D"color:rgb(102,102,0)">&amp;</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,13=
6)">operator</span><span style=3D"color:rgb(102,102,0)">=3D(</span><span st=
yle=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> st=
ack_array</span><span style=3D"color:rgb(102,102,0)">&amp;)</span><span sty=
le=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</s=
pan><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,1=
36)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span style=
=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102=
,102,0)">~</span><span style=3D"color:rgb(0,0,0)">stack_array</span><span s=
tyle=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">default</span><span st=
yle=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br><=
br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(136,0,0)">/* ... */</span>=
<span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,10=
2,0)">};</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></d=
iv><br>Now, to standardize that kind of stuff, I think we should speak in t=
erms of scopes:</div><div>the internal scope of an inline! function is the =
same as the scope where the call is performed.</div><div>As the alloca memo=
ry is &quot;deallocated&quot; at the end of the scope, we have the expected=
 behavior.</div><div><br></div><div>For this to work, the definition of the=
 inline! function must be visible at the call site, and the simplest way to=
 implement it in the compiler is to actually perform inlining.</div><div>Wi=
th such a definition, inline! cannot be implemented with an attribute as it=
 changes the semantic of the program, and cannot be ignored.<br></div></div=
></blockquote><div><br></div><div>People compile their code and when they d=
on&#39;t get the result they want, they use __forceinline or=C2=A0always_in=
line or resort to that immediately.</div><div>At that point they now have c=
ompiler specific code and macros. If they had inline! in terms=C2=A0in the =
mentioned they would have less of that type of code.</div><div>My descripti=
on of inline! if defined in terms of __forceinline and always_inline.</div>=
<div><br></div><div>What you are after sounds like something more complicat=
ed and therefore a=C2=A0different feature than what my suggestion is aiming=
 for.</div><div>I&#39;ve little doubt that what you want is of value but yo=
u are opening more cans of worms to get it.</div><div>A question to ask als=
o is does your feature likely promise to do the thing that=C2=A0makes peopl=
e reach for=C2=A0__forceinline and always_inline.</div><div><br></div><div>=
I don&#39;t really have much of a problem with anything you&#39;ve said oth=
er than I think if everyone heads off to define that what you are talking a=
bout I suspect it&#39;ll be something else to what I&#39;m proposing.=C2=A0=
If it makes C++ better, ok. It seems there are a few features in this space=
 that people need.</div></div></blockquote><div><br></div><div>What I&#39;m=
 after is a way to integrate force inlining into the language using the ter=
ms of the language itself.</div><div>Inlining is an optimization, and like =
any other optimizations, it is outside the language.</div><div>You could sa=
y mandatory RVO is an exception, but actually, this optimization is express=
ed within the language itself, and not like an optimization (with prvalues =
and copy elision).</div><div><br></div><div>If you want to integrate an opt=
imization within the language itself, it should makes something possible:</=
div><div>mandatory copy elision allows to return non-copyable, non moveable=
 objects.</div><div>In case of forced inlining, it would allow to allocate =
objects in the caller scope.</div><div><br></div><div>So what I propose is =
actually simpler to standardize than force inlining because it can be expre=
ssed much more easily than inlining itself within the language.</div><div><=
br></div><div>Moreover, with the way I expressed it, the simplest implement=
ation would be to force inline. (We probably want to disallow recursion on =
those functions)<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/faa625d2-380a-4eff-aa14-e26f20f03d1b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/faa625d2-380a-4eff-aa14-e26f20f03d1b=
%40isocpp.org</a>.<br />

------=_Part_127439_730532058.1531314242523--

------=_Part_127438_1926152162.1531314242523--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Wed, 11 Jul 2018 15:31:05 +0200
Raw View
--000000000000db90e10570b94236
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 11 Jul 2018 at 15:04, <florian.csdt@gmail.com> wrote:

>
>
> Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a =C3=A9cri=
t :
>>
>>
>>
>> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.com
>> wrote:
>>>
>>>
>>> I would like to highlight some facts: the inline keyword is not about
>>> inlining. As already said by others, the abstract machine has no notion=
 of
>>> what is inlining.
>>> The reason is simple: inlining doesn't change the behavior of a program=
,
>>> only its speed (and stack usage in some cases).
>>> The abstract machine doesn't care about speed, only the bahavior.
>>>
>>
>> I'm not sure keep thinking about inline on it's own is helpful to my
>> case, though perhaps it might be for your case.
>> But see my comment later.
>>
>>
>>
>>>
>>> Currently, what inline is about is multiple definition of a single
>>> function/object across translation units.
>>> If you want extra information, have a look at
>>> https://en.cppreference.com/w/cpp/language/inline
>>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw%2=
Fcpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6n=
FcNoCw>
>>>
>>> That being said, it would still be interested to have a force inline.
>>> The best example I can think of is calling alloca within a function, an=
d
>>> returning the pointer. On every compilers I tested, the allocated stack
>>> memory is kept after this call iif the call is actually inlined.
>>> One use case would be runtime size class:
>>> template class T>
>>> class stack_array {
>>>   private:
>>>     T* p;
>>>   public:
>>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>>     stack_array() =3D delete;
>>>     stack_array(const stack_array&) =3D delete;
>>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>>     ~stack_array() =3D default;
>>>
>>>     /* ... */
>>> };
>>>
>>> Now, to standardize that kind of stuff, I think we should speak in term=
s
>>> of scopes:
>>> the internal scope of an inline! function is the same as the scope wher=
e
>>> the call is performed.
>>> As the alloca memory is "deallocated" at the end of the scope, we have
>>> the expected behavior.
>>>
>>> For this to work, the definition of the inline! function must be visibl=
e
>>> at the call site, and the simplest way to implement it in the compiler =
is
>>> to actually perform inlining.
>>> With such a definition, inline! cannot be implemented with an attribute
>>> as it changes the semantic of the program, and cannot be ignored.
>>>
>>
>> People compile their code and when they don't get the result they want,
>> they use __forceinline or always_inline or resort to that immediately.
>> At that point they now have compiler specific code and macros. If they
>> had inline! in terms in the mentioned they would have less of that type =
of
>> code.
>> My description of inline! if defined in terms of __forceinline and
>> always_inline.
>>
>> What you are after sounds like something more complicated and therefore
>> a different feature than what my suggestion is aiming for.
>> I've little doubt that what you want is of value but you are opening mor=
e
>> cans of worms to get it.
>> A question to ask also is does your feature likely promise to do the
>> thing that makes people reach for __forceinline and always_inline.
>>
>> I don't really have much of a problem with anything you've said other
>> than I think if everyone heads off to define that what you are talking
>> about I suspect it'll be something else to what I'm proposing. If it mak=
es
>> C++ better, ok. It seems there are a few features in this space that peo=
ple
>> need.
>>
>
> What I'm after is a way to integrate force inlining into the language
> using the terms of the language itself.
> Inlining is an optimization, and like any other optimizations, it is
> outside the language.
> You could say mandatory RVO is an exception, but actually, this
> optimization is expressed within the language itself, and not like an
> optimization (with prvalues and copy elision).
>
> If you want to integrate an optimization within the language itself, it
> should makes something possible:
> mandatory copy elision allows to return non-copyable, non moveable object=
s.
> In case of forced inlining, it would allow to allocate objects in the
> caller scope.
>

This is already available, and can be fully expressed in the language as
is.
Either by dependency injection or passing a reference to
std::aligned_storage, depending on when you want the constructor/destructor
to fire.
Why someone would want to express in which stack frame to store the object
as *semantic intent* is a mystery to me. It's an implementation detail (as
is the idea of a stack frame!). Therefore it is non-portable. Therefore it
has no place in the language.


>
> So what I propose is actually simpler to standardize than force inlining
> because it can be expressed much more easily than inlining itself within
> the language.
>
> Moreover, with the way I expressed it, the simplest implementation would
> be to force inline. (We probably want to disallow recursion on those
> functions)
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/faa625d2-380=
a-4eff-aa14-e26f20f03d1b%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/faa625d2-38=
0a-4eff-aa14-e26f20f03d1b%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hb%3D0XjVACgSdNO6gnUT_whA3pFbRrYQs4WP5PVhE=
i1Mmg%40mail.gmail.com.

--000000000000db90e10570b94236
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, 11 Jul 2018 at 15:04, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 12:35:12 UTC+2, <a href=
=3D"mailto:gmis...@gmail.com" target=3D"_blank">gmis...@gmail.com</a> a =C3=
=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>=
<br>On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, <a>floria...@gmail.co=
m</a> wrote:<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-left-style:solid"><div dir=3D"ltr"><div><br></div><div>I would l=
ike to highlight some facts: the <span style=3D"font-family:courier new,mon=
ospace">inline</span> keyword is not about inlining. As already said by oth=
ers, the abstract machine has no notion of what is inlining.</div><div>The =
reason is simple: inlining doesn&#39;t change the behavior of a program, on=
ly its speed (and stack usage in some cases).</div><div>The abstract machin=
e doesn&#39;t care about speed, only the bahavior.</div></div></blockquote>=
<div><br></div><div>I&#39;m not sure keep thinking about inline on it&#39;s=
 own is helpful to my case,=C2=A0though perhaps it might be for your case.<=
/div><div>But see my comment later.</div><div><br></div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-l=
eft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-lef=
t-style:solid"><div dir=3D"ltr"><div><br></div><div>Currently, what <span s=
tyle=3D"font-family:courier new,monospace">inline</span> is about is multip=
le definition of a single function/object across translation units.<br></di=
v><div>If you want extra information, have a look at <a href=3D"https://www=
..google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%=
2Finline&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6nFcNo=
Cw" rel=3D"nofollow" target=3D"_blank">https://en.cppreference.com/w/cpp/la=
nguage/inline</a></div><div><br></div><div>That being said, it would still =
be interested to have a force inline.</div><div>The best example I can thin=
k of is calling alloca within a function, and returning the pointer. On eve=
ry compilers I tested, the allocated stack memory is kept after this call i=
if the call is actually inlined.</div><div>One use case would be runtime si=
ze class:</div><div><div style=3D"border:1px solid rgb(187,187,187);backgro=
und-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">t=
emplate</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color=
:rgb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> T</span><span =
style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)">=
<br></span><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"co=
lor:rgb(0,0,0)"> stack_array </span><span style=3D"color:rgb(102,102,0)">{<=
/span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"col=
or:rgb(0,0,136)">private</span><span style=3D"color:rgb(102,102,0)">:</span=
><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 T</span><span style=3D"=
color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> p</span><sp=
an style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)">=
<br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">public</span><span sty=
le=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">inline</span><span =
style=3D"color:rgb(102,102,0)">!</span><span style=3D"color:rgb(0,0,0)"> st=
ack_array</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D=
"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> n</span><s=
pan style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:=
rgb(0,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">(</span><span sty=
le=3D"color:rgb(0,0,0)">alloca</span><span style=3D"color:rgb(102,102,0)">(=
</span><span style=3D"color:rgb(0,0,0)">n </span><span style=3D"color:rgb(1=
02,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"=
color:rgb(0,0,136)">sizeof</span><span style=3D"color:rgb(102,102,0)">(</sp=
an><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:rgb(102,10=
2,0)">)))</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"col=
or:rgb(102,102,0)">{}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 stack_array</span><span style=3D"color:rgb(102,102,0)">()</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D<=
/span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0=
,136)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span styl=
e=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"c=
olor:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span=
><span style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:r=
gb(102,102,0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color=
:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0=
 stack_array</span><span style=3D"color:rgb(102,102,0)">&amp;</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">operat=
or</span><span style=3D"color:rgb(102,102,0)">=3D(</span><span style=3D"col=
or:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> stack_array<=
/span><span style=3D"color:rgb(102,102,0)">&amp;)</span><span style=3D"colo=
r:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">delet=
e</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)">~<=
/span><span style=3D"color:rgb(0,0,0)">stack_array</span><span style=3D"col=
or:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(0,0,136)">default</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(136,0,0)">/* ... */</span><span styl=
e=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};</=
span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></div><br>Now=
, to standardize that kind of stuff, I think we should speak in terms of sc=
opes:</div><div>the internal scope of an inline! function is the same as th=
e scope where the call is performed.</div><div>As the alloca memory is &quo=
t;deallocated&quot; at the end of the scope, we have the expected behavior.=
</div><div><br></div><div>For this to work, the definition of the inline! f=
unction must be visible at the call site, and the simplest way to implement=
 it in the compiler is to actually perform inlining.</div><div>With such a =
definition, inline! cannot be implemented with an attribute as it changes t=
he semantic of the program, and cannot be ignored.<br></div></div></blockqu=
ote><div><br></div><div>People compile their code and when they don&#39;t g=
et the result they want, they use __forceinline or=C2=A0always_inline or re=
sort to that immediately.</div><div>At that point they now have compiler sp=
ecific code and macros. If they had inline! in terms=C2=A0in the mentioned =
they would have less of that type of code.</div><div>My description of inli=
ne! if defined in terms of __forceinline and always_inline.</div><div><br><=
/div><div>What you are after sounds like something more complicated and the=
refore a=C2=A0different feature than what my suggestion is aiming for.</div=
><div>I&#39;ve little doubt that what you want is of value but you are open=
ing more cans of worms to get it.</div><div>A question to ask also is does =
your feature likely promise to do the thing that=C2=A0makes people reach fo=
r=C2=A0__forceinline and always_inline.</div><div><br></div><div>I don&#39;=
t really have much of a problem with anything you&#39;ve said other than I =
think if everyone heads off to define that what you are talking about I sus=
pect it&#39;ll be something else to what I&#39;m proposing.=C2=A0If it make=
s C++ better, ok. It seems there are a few features in this space that peop=
le need.</div></div></blockquote><div><br></div><div>What I&#39;m after is =
a way to integrate force inlining into the language using the terms of the =
language itself.</div><div>Inlining is an optimization, and like any other =
optimizations, it is outside the language.</div><div>You could say mandator=
y RVO is an exception, but actually, this optimization is expressed within =
the language itself, and not like an optimization (with prvalues and copy e=
lision).</div><div><br></div><div>If you want to integrate an optimization =
within the language itself, it should makes something possible:</div><div>m=
andatory copy elision allows to return non-copyable, non moveable objects.<=
/div><div>In case of forced inlining, it would allow to allocate objects in=
 the caller scope.</div></div></blockquote><div><br></div><div>This is alre=
ady available, and can be fully expressed in the language as is.=C2=A0</div=
><div>Either by dependency injection or passing a reference to=C2=A0<font f=
ace=3D"monospace, monospace">std::aligned_storage</font>, depending on when=
 you want the constructor/destructor to fire.=C2=A0</div><div>Why someone w=
ould want to express in which stack frame to store the object as <i><u>sema=
ntic intent</u></i> is a mystery to me. It&#39;s an implementation detail (=
as is the idea of a stack frame!). Therefore it is non-portable. Therefore =
it has no place in the language.</div><div>=C2=A0<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><br></div><div>So what I propose is ac=
tually simpler to standardize than force inlining because it can be express=
ed much more easily than inlining itself within the language.</div><div><br=
></div><div>Moreover, with the way I expressed it, the simplest implementat=
ion would be to force inline. (We probably want to disallow recursion on th=
ose functions)<br></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/faa625d2-380a-4eff-aa14-e26f20f03d1b%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/faa625d2-380a-=
4eff-aa14-e26f20f03d1b%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hb%3D0XjVACgSdNO6gnUT_whA3pFbRr=
YQs4WP5PVhEi1Mmg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hb%3D0XjV=
ACgSdNO6gnUT_whA3pFbRrYQs4WP5PVhEi1Mmg%40mail.gmail.com</a>.<br />

--000000000000db90e10570b94236--

.


Author: florian.csdt@gmail.com
Date: Wed, 11 Jul 2018 06:54:03 -0700 (PDT)
Raw View
------=_Part_127714_1715142958.1531317243508
Content-Type: multipart/alternative;
 boundary="----=_Part_127715_556448260.1531317243509"

------=_Part_127715_556448260.1531317243509
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9crit :
>
>
>
> On Wed, 11 Jul 2018 at 15:04, <floria...@gmail.com <javascript:>> wrote:
>
>>
>>
>> Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a =C3=A9cr=
it :
>>>
>>>
>>>
>>> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.com=
=20
>>> wrote:
>>>>
>>>>
>>>> I would like to highlight some facts: the inline keyword is not about=
=20
>>>> inlining. As already said by others, the abstract machine has no notio=
n of=20
>>>> what is inlining.
>>>> The reason is simple: inlining doesn't change the behavior of a=20
>>>> program, only its speed (and stack usage in some cases).
>>>> The abstract machine doesn't care about speed, only the bahavior.
>>>>
>>>
>>> I'm not sure keep thinking about inline on it's own is helpful to my=20
>>> case, though perhaps it might be for your case.
>>> But see my comment later.
>>>
>>> =20
>>>
>>>>
>>>> Currently, what inline is about is multiple definition of a single=20
>>>> function/object across translation units.
>>>> If you want extra information, have a look at=20
>>>> https://en.cppreference.com/w/cpp/language/inline=20
>>>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw%=
2Fcpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6=
nFcNoCw>
>>>>
>>>> That being said, it would still be interested to have a force inline.
>>>> The best example I can think of is calling alloca within a function,=
=20
>>>> and returning the pointer. On every compilers I tested, the allocated =
stack=20
>>>> memory is kept after this call iif the call is actually inlined.
>>>> One use case would be runtime size class:
>>>> template class T>
>>>> class stack_array {
>>>>   private:
>>>>     T* p;
>>>>   public:
>>>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>>>     stack_array() =3D delete;
>>>>     stack_array(const stack_array&) =3D delete;
>>>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>>>     ~stack_array() =3D default;
>>>>
>>>>     /* ... */
>>>> };
>>>>
>>>> Now, to standardize that kind of stuff, I think we should speak in=20
>>>> terms of scopes:
>>>> the internal scope of an inline! function is the same as the scope=20
>>>> where the call is performed.
>>>> As the alloca memory is "deallocated" at the end of the scope, we have=
=20
>>>> the expected behavior.
>>>>
>>>> For this to work, the definition of the inline! function must be=20
>>>> visible at the call site, and the simplest way to implement it in the=
=20
>>>> compiler is to actually perform inlining.
>>>> With such a definition, inline! cannot be implemented with an attribut=
e=20
>>>> as it changes the semantic of the program, and cannot be ignored.
>>>>
>>>
>>> People compile their code and when they don't get the result they want,=
=20
>>> they use __forceinline or always_inline or resort to that immediately.
>>> At that point they now have compiler specific code and macros. If they=
=20
>>> had inline! in terms in the mentioned they would have less of that type=
 of=20
>>> code.
>>> My description of inline! if defined in terms of __forceinline and=20
>>> always_inline.
>>>
>>> What you are after sounds like something more complicated and therefore=
=20
>>> a different feature than what my suggestion is aiming for.
>>> I've little doubt that what you want is of value but you are opening=20
>>> more cans of worms to get it.
>>> A question to ask also is does your feature likely promise to do the=20
>>> thing that makes people reach for __forceinline and always_inline.
>>>
>>> I don't really have much of a problem with anything you've said other=
=20
>>> than I think if everyone heads off to define that what you are talking=
=20
>>> about I suspect it'll be something else to what I'm proposing. If it ma=
kes=20
>>> C++ better, ok. It seems there are a few features in this space that pe=
ople=20
>>> need.
>>>
>>
>> What I'm after is a way to integrate force inlining into the language=20
>> using the terms of the language itself.
>> Inlining is an optimization, and like any other optimizations, it is=20
>> outside the language.
>> You could say mandatory RVO is an exception, but actually, this=20
>> optimization is expressed within the language itself, and not like an=20
>> optimization (with prvalues and copy elision).
>>
>> If you want to integrate an optimization within the language itself, it=
=20
>> should makes something possible:
>> mandatory copy elision allows to return non-copyable, non moveable=20
>> objects.
>> In case of forced inlining, it would allow to allocate objects in the=20
>> caller scope.
>>
>
> This is already available, and can be fully expressed in the language as=
=20
> is.=20
> Either by dependency injection or passing a reference to=20
> std::aligned_storage, depending on when you want the=20
> constructor/destructor to fire.=20
> Why someone would want to express in which stack frame to store the objec=
t=20
> as *semantic intent* is a mystery to me. It's an implementation detail=20
> (as is the idea of a stack frame!). Therefore it is non-portable. Therefo=
re=20
> it has no place in the language.
>

No, in the implementation you propose the storage is allocated by caller,=
=20
and passed to the callee. But the caller might not know how much the callee=
=20
wants to allocate.

Also, I never talked about stack frame, which are unknown to the language.=
=20
I talked about scopes (which is in practice related to stack frames).
Scopes have 2 purposes: specifying which names are visibles, and specifying=
=20
when objects are destructed.
What I propose is to change the second point for inline! functions. This=20
would be a semantic change, not just an implementation change.

The intent would be: the locals of an inline! function outlive the function=
=20
call, and will be destroyed at the same time as the caller locals, ie:=20
callee and caller locals are in the same scope.
I'm pretty sure you could use it to avoid some dangling references.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/07767bd5-cd9f-4b9a-bee4-076ab043ccaa%40isocpp.or=
g.

------=_Part_127715_556448260.1531317243509
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richar=
d Hodges a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, =
11 Jul 2018 at 15:04, &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"QAVPip1mBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;">floria...@gmail.com</a>&gt; wrote:<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018=
 12:35:12 UTC+2, <a>gmis...@gmail.com</a> a =C3=A9crit=C2=A0:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Wednesday, July 11, 2=
018 at 8:23:51 PM UTC+12, <a>floria...@gmail.com</a> wrote:<blockquote clas=
s=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-left-style:solid"=
><div dir=3D"ltr"><div><br></div><div>I would like to highlight some facts:=
 the <span style=3D"font-family:courier new,monospace">inline</span> keywor=
d is not about inlining. As already said by others, the abstract machine ha=
s no notion of what is inlining.</div><div>The reason is simple: inlining d=
oesn&#39;t change the behavior of a program, only its speed (and stack usag=
e in some cases).</div><div>The abstract machine doesn&#39;t care about spe=
ed, only the bahavior.</div></div></blockquote><div><br></div><div>I&#39;m =
not sure keep thinking about inline on it&#39;s own is helpful to my case,=
=C2=A0though perhaps it might be for your case.</div><div>But see my commen=
t later.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:r=
gb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"=
ltr"><div><br></div><div>Currently, what <span style=3D"font-family:courier=
 new,monospace">inline</span> is about is multiple definition of a single f=
unction/object across translation units.<br></div><div>If you want extra in=
formation, have a look at <a href=3D"https://www.google.com/url?q=3Dhttps%3=
A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline&amp;sa=3DD&amp;snt=
z=3D1&amp;usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw" rel=3D"nofollow" target=
=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3=
dhttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true=
;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%=
2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true;">https://en=
..cppreference.com/w/<wbr>cpp/language/inline</a></div><div><br></div><div>T=
hat being said, it would still be interested to have a force inline.</div><=
div>The best example I can think of is calling alloca within a function, an=
d returning the pointer. On every compilers I tested, the allocated stack m=
emory is kept after this call iif the call is actually inlined.</div><div>O=
ne use case would be runtime size class:</div><div><div style=3D"border:1px=
 solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><span=
 style=3D"color:rgb(0,0,136)">template</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"co=
lor:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><s=
pan style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)=
">class</span><span style=3D"color:rgb(0,0,0)"> stack_array </span><span st=
yle=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">private</span><span style=
=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 T</span><span style=3D"color:rgb(102,102,0)">*</span><span style=
=3D"color:rgb(0,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">;</span=
><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rg=
b(0,0,136)">public</span><span style=3D"color:rgb(102,102,0)">:</span><span=
 style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:r=
gb(0,0,136)">inline</span><span style=3D"color:rgb(102,102,0)">!</span><spa=
n style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style=3D"color:rgb(0,0,136)">int</span><span style=
=3D"color:rgb(0,0,0)"> n</span><span style=3D"color:rgb(102,102,0)">)</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,=
0)">:</span><span style=3D"color:rgb(0,0,0)"> p</span><span style=3D"color:=
rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">alloca</span><span=
 style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">n =
</span><span style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">sizeof</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">T</spa=
n><span style=3D"color:rgb(102,102,0)">)))</span><span style=3D"color:rgb(0=
,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{}</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:r=
gb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 s=
tack_array</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> stack=
_array</span><span style=3D"color:rgb(102,102,0)">&amp;)</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">&amp;</span><span style=3D"color:rgb(0,0,0)"> </span><span=
 style=3D"color:rgb(0,0,136)">operator</span><span style=3D"color:rgb(102,1=
02,0)">=3D(</span><span style=3D"color:rgb(0,0,136)">const</span><span styl=
e=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(102,102,=
0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:rgb(102,10=
2,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:rgb(102,102,0)">~</span><span style=3D"color:rgb(0,0,0)">=
stack_array</span><span style=3D"color:rgb(102,102,0)">()</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">default</span><span style=3D"color:rgb(102,102,0)">;</span><span style=
=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb=
(136,0,0)">/* ... */</span><span style=3D"color:rgb(0,0,0)"><br></span><spa=
n style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)">=
<br></span></div></code></div><br>Now, to standardize that kind of stuff, I=
 think we should speak in terms of scopes:</div><div>the internal scope of =
an inline! function is the same as the scope where the call is performed.</=
div><div>As the alloca memory is &quot;deallocated&quot; at the end of the =
scope, we have the expected behavior.</div><div><br></div><div>For this to =
work, the definition of the inline! function must be visible at the call si=
te, and the simplest way to implement it in the compiler is to actually per=
form inlining.</div><div>With such a definition, inline! cannot be implemen=
ted with an attribute as it changes the semantic of the program, and cannot=
 be ignored.<br></div></div></blockquote><div><br></div><div>People compile=
 their code and when they don&#39;t get the result they want, they use __fo=
rceinline or=C2=A0always_inline or resort to that immediately.</div><div>At=
 that point they now have compiler specific code and macros. If they had in=
line! in terms=C2=A0in the mentioned they would have less of that type of c=
ode.</div><div>My description of inline! if defined in terms of __forceinli=
ne and always_inline.</div><div><br></div><div>What you are after sounds li=
ke something more complicated and therefore a=C2=A0different feature than w=
hat my suggestion is aiming for.</div><div>I&#39;ve little doubt that what =
you want is of value but you are opening more cans of worms to get it.</div=
><div>A question to ask also is does your feature likely promise to do the =
thing that=C2=A0makes people reach for=C2=A0__forceinline and always_inline=
..</div><div><br></div><div>I don&#39;t really have much of a problem with a=
nything you&#39;ve said other than I think if everyone heads off to define =
that what you are talking about I suspect it&#39;ll be something else to wh=
at I&#39;m proposing.=C2=A0If it makes C++ better, ok. It seems there are a=
 few features in this space that people need.</div></div></blockquote><div>=
<br></div><div>What I&#39;m after is a way to integrate force inlining into=
 the language using the terms of the language itself.</div><div>Inlining is=
 an optimization, and like any other optimizations, it is outside the langu=
age.</div><div>You could say mandatory RVO is an exception, but actually, t=
his optimization is expressed within the language itself, and not like an o=
ptimization (with prvalues and copy elision).</div><div><br></div><div>If y=
ou want to integrate an optimization within the language itself, it should =
makes something possible:</div><div>mandatory copy elision allows to return=
 non-copyable, non moveable objects.</div><div>In case of forced inlining, =
it would allow to allocate objects in the caller scope.</div></div></blockq=
uote><div><br></div><div>This is already available, and can be fully expres=
sed in the language as is.=C2=A0</div><div>Either by dependency injection o=
r passing a reference to=C2=A0<font face=3D"monospace, monospace">std::alig=
ned_storage</font>, depending on when you want the constructor/destructor t=
o fire.=C2=A0</div><div>Why someone would want to express in which stack fr=
ame to store the object as <i><u>semantic intent</u></i> is a mystery to me=
.. It&#39;s an implementation detail (as is the idea of a stack frame!). The=
refore it is non-portable. Therefore it has no place in the language.</div>=
</div></div></blockquote><div><br></div><div>No, in the implementation you =
propose the storage is allocated by caller, and passed to the callee. But t=
he caller might not know how much the callee wants to allocate.</div><div><=
br></div><div>Also, I never talked about stack frame, which are unknown to =
the language. I talked about scopes (which is in practice related to stack =
frames).</div><div>Scopes have 2 purposes: specifying which names are visib=
les, and specifying when objects are destructed.</div><div>What I propose i=
s to change the second point for inline! functions. This would be a semanti=
c change, not just an implementation change.</div><div><br></div><div>The i=
ntent would be: the locals of an inline! function outlive the function call=
, and will be destroyed at the same time as the caller locals, ie: callee a=
nd caller locals are in the same scope.</div><div>I&#39;m pretty sure you c=
ould use it to avoid some dangling references.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/07767bd5-cd9f-4b9a-bee4-076ab043ccaa%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/07767bd5-cd9f-4b9a-bee4-076ab043ccaa=
%40isocpp.org</a>.<br />

------=_Part_127715_556448260.1531317243509--

------=_Part_127714_1715142958.1531317243508--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Wed, 11 Jul 2018 16:12:52 +0200
Raw View
--000000000000346b3d0570b9d8b9
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 11 Jul 2018 at 15:54, <florian.csdt@gmail.com> wrote:

>
>
> Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9crit :
>>
>>
>>
>> On Wed, 11 Jul 2018 at 15:04, <floria...@gmail.com> wrote:
>>
>>>
>>>
>>> Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a =C3=A9c=
rit :
>>>>
>>>>
>>>>
>>>> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.com
>>>> wrote:
>>>>>
>>>>>
>>>>> I would like to highlight some facts: the inline keyword is not about
>>>>> inlining. As already said by others, the abstract machine has no noti=
on of
>>>>> what is inlining.
>>>>> The reason is simple: inlining doesn't change the behavior of a
>>>>> program, only its speed (and stack usage in some cases).
>>>>> The abstract machine doesn't care about speed, only the bahavior.
>>>>>
>>>>
>>>> I'm not sure keep thinking about inline on it's own is helpful to my
>>>> case, though perhaps it might be for your case.
>>>> But see my comment later.
>>>>
>>>>
>>>>
>>>>>
>>>>> Currently, what inline is about is multiple definition of a single
>>>>> function/object across translation units.
>>>>> If you want extra information, have a look at
>>>>> https://en.cppreference.com/w/cpp/language/inline
>>>>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw=
%2Fcpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7uAN=
6nFcNoCw>
>>>>>
>>>>> That being said, it would still be interested to have a force inline.
>>>>> The best example I can think of is calling alloca within a function,
>>>>> and returning the pointer. On every compilers I tested, the allocated=
 stack
>>>>> memory is kept after this call iif the call is actually inlined.
>>>>> One use case would be runtime size class:
>>>>> template class T>
>>>>> class stack_array {
>>>>>   private:
>>>>>     T* p;
>>>>>   public:
>>>>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>>>>     stack_array() =3D delete;
>>>>>     stack_array(const stack_array&) =3D delete;
>>>>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>>>>     ~stack_array() =3D default;
>>>>>
>>>>>     /* ... */
>>>>> };
>>>>>
>>>>> Now, to standardize that kind of stuff, I think we should speak in
>>>>> terms of scopes:
>>>>> the internal scope of an inline! function is the same as the scope
>>>>> where the call is performed.
>>>>> As the alloca memory is "deallocated" at the end of the scope, we hav=
e
>>>>> the expected behavior.
>>>>>
>>>>> For this to work, the definition of the inline! function must be
>>>>> visible at the call site, and the simplest way to implement it in the
>>>>> compiler is to actually perform inlining.
>>>>> With such a definition, inline! cannot be implemented with an
>>>>> attribute as it changes the semantic of the program, and cannot be ig=
nored.
>>>>>
>>>>
>>>> People compile their code and when they don't get the result they want=
,
>>>> they use __forceinline or always_inline or resort to that immediately.
>>>> At that point they now have compiler specific code and macros. If they
>>>> had inline! in terms in the mentioned they would have less of that typ=
e of
>>>> code.
>>>> My description of inline! if defined in terms of __forceinline and
>>>> always_inline.
>>>>
>>>> What you are after sounds like something more complicated and therefor=
e
>>>> a different feature than what my suggestion is aiming for.
>>>> I've little doubt that what you want is of value but you are opening
>>>> more cans of worms to get it.
>>>> A question to ask also is does your feature likely promise to do the
>>>> thing that makes people reach for __forceinline and always_inline.
>>>>
>>>> I don't really have much of a problem with anything you've said other
>>>> than I think if everyone heads off to define that what you are talking
>>>> about I suspect it'll be something else to what I'm proposing. If it m=
akes
>>>> C++ better, ok. It seems there are a few features in this space that p=
eople
>>>> need.
>>>>
>>>
>>> What I'm after is a way to integrate force inlining into the language
>>> using the terms of the language itself.
>>> Inlining is an optimization, and like any other optimizations, it is
>>> outside the language.
>>> You could say mandatory RVO is an exception, but actually, this
>>> optimization is expressed within the language itself, and not like an
>>> optimization (with prvalues and copy elision).
>>>
>>> If you want to integrate an optimization within the language itself, it
>>> should makes something possible:
>>> mandatory copy elision allows to return non-copyable, non moveable
>>> objects.
>>> In case of forced inlining, it would allow to allocate objects in the
>>> caller scope.
>>>
>>
>> This is already available, and can be fully expressed in the language as
>> is.
>> Either by dependency injection or passing a reference to
>> std::aligned_storage, depending on when you want the
>> constructor/destructor to fire.
>> Why someone would want to express in which stack frame to store the
>> object as *semantic intent* is a mystery to me. It's an implementation
>> detail (as is the idea of a stack frame!). Therefore it is non-portable.
>> Therefore it has no place in the language.
>>
>
> No, in the implementation you propose the storage is allocated by caller,
> and passed to the callee. But the caller might not know how much the call=
ee
> wants to allocate.
>
> Also, I never talked about stack frame, which are unknown to the language=
..
> I talked about scopes (which is in practice related to stack frames).
> Scopes have 2 purposes: specifying which names are visibles, and
> specifying when objects are destructed.
> What I propose is to change the second point for inline! functions. This
> would be a semantic change, not just an implementation change.
>
> The intent would be: the locals of an inline! function outlive the
> function call, and will be destroyed at the same time as the caller local=
s,
> ie: callee and caller locals are in the same scope.
> I'm pretty sure you could use it to avoid some dangling references.
>

This is already expressible:

#include <tuple>
#include <string>

std::tuple<int, std::string> foo();

std::size_t bar()
{
  auto&& [ a, b ] =3D foo();
  return a + b.size();  // a and b outlive scope of foo()
}




> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/07767bd5-cd9=
f-4b9a-bee4-076ab043ccaa%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/07767bd5-cd=
9f-4b9a-bee4-076ab043ccaa%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hbvsBe6o-EW9%3DK%3D0NmvteuHphGOotYScrGEG8e=
MjYj8Kw%40mail.gmail.com.

--000000000000346b3d0570b9d8b9
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, 11 Jul 2018 at 15:54, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard =
Hodges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, 11 Jul=
 2018 at 15:04, &lt;<a rel=3D"nofollow">floria...@gmail.com</a>&gt; wrote:<=
br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le mercred=
i 11 juillet 2018 12:35:12 UTC+2, <a>gmis...@gmail.com</a> a =C3=A9crit=C2=
=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Wed=
nesday, July 11, 2018 at 8:23:51 PM UTC+12, <a>floria...@gmail.com</a> wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;paddi=
ng-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border=
-left-style:solid"><div dir=3D"ltr"><div><br></div><div>I would like to hig=
hlight some facts: the <span style=3D"font-family:courier new,monospace">in=
line</span> keyword is not about inlining. As already said by others, the a=
bstract machine has no notion of what is inlining.</div><div>The reason is =
simple: inlining doesn&#39;t change the behavior of a program, only its spe=
ed (and stack usage in some cases).</div><div>The abstract machine doesn&#3=
9;t care about speed, only the bahavior.</div></div></blockquote><div><br><=
/div><div>I&#39;m not sure keep thinking about inline on it&#39;s own is he=
lpful to my case,=C2=A0though perhaps it might be for your case.</div><div>=
But see my comment later.</div><div><br></div><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;bo=
rder-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:so=
lid"><div dir=3D"ltr"><div><br></div><div>Currently, what <span style=3D"fo=
nt-family:courier new,monospace">inline</span> is about is multiple definit=
ion of a single function/object across translation units.<br></div><div>If =
you want extra information, have a look at <a href=3D"https://www.google.co=
m/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline&a=
mp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw" rel=3D=
"nofollow" target=3D"_blank">https://en.cppreference.com/w/cpp/language/inl=
ine</a></div><div><br></div><div>That being said, it would still be interes=
ted to have a force inline.</div><div>The best example I can think of is ca=
lling alloca within a function, and returning the pointer. On every compile=
rs I tested, the allocated stack memory is kept after this call iif the cal=
l is actually inlined.</div><div>One use case would be runtime size class:<=
/div><div><div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">template</s=
pan><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,1=
36)">class</span><span style=3D"color:rgb(0,0,0)"> T</span><span style=3D"c=
olor:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"><br></span=
><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"color:rgb(0,=
0,0)"> stack_array </span><span style=3D"color:rgb(102,102,0)">{</span><spa=
n style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(0,0=
,136)">private</span><span style=3D"color:rgb(102,102,0)">:</span><span sty=
le=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 T</span><span style=3D"color:rgb(=
102,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> p</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 </span><span style=3D"color:rgb(0,0,136)">public</span><span style=3D"c=
olor:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">inline</span><span style=
=3D"color:rgb(102,102,0)">!</span><span style=3D"color:rgb(0,0,0)"> stack_a=
rray</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"colo=
r:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> n</span><span s=
tyle=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </s=
pan><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0=
,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D=
"color:rgb(0,0,0)">alloca</span><span style=3D"color:rgb(102,102,0)">(</spa=
n><span style=3D"color:rgb(0,0,0)">n </span><span style=3D"color:rgb(102,10=
2,0)">*</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color=
:rgb(0,0,136)">sizeof</span><span style=3D"color:rgb(102,102,0)">(</span><s=
pan style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:rgb(102,102,0)"=
>)))</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rg=
b(102,102,0)">{}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 s=
tack_array</span><span style=3D"color:rgb(102,102,0)">()</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span><sp=
an style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(1=
02,102,0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span><span styl=
e=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </sp=
an><span style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:rgb=
(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 sta=
ck_array</span><span style=3D"color:rgb(102,102,0)">&amp;</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">operator</=
span><span style=3D"color:rgb(102,102,0)">=3D(</span><span style=3D"color:r=
gb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> stack_array</spa=
n><span style=3D"color:rgb(102,102,0)">&amp;)</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">delete</s=
pan><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0=
,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)">~</spa=
n><span style=3D"color:rgb(0,0,0)">stack_array</span><span style=3D"color:r=
gb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span styl=
e=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </sp=
an><span style=3D"color:rgb(0,0,136)">default</span><span style=3D"color:rg=
b(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:rgb(136,0,0)">/* ... */</span><span style=
=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};</s=
pan><span style=3D"color:rgb(0,0,0)"><br></span></div></code></div><br>Now,=
 to standardize that kind of stuff, I think we should speak in terms of sco=
pes:</div><div>the internal scope of an inline! function is the same as the=
 scope where the call is performed.</div><div>As the alloca memory is &quot=
;deallocated&quot; at the end of the scope, we have the expected behavior.<=
/div><div><br></div><div>For this to work, the definition of the inline! fu=
nction must be visible at the call site, and the simplest way to implement =
it in the compiler is to actually perform inlining.</div><div>With such a d=
efinition, inline! cannot be implemented with an attribute as it changes th=
e semantic of the program, and cannot be ignored.<br></div></div></blockquo=
te><div><br></div><div>People compile their code and when they don&#39;t ge=
t the result they want, they use __forceinline or=C2=A0always_inline or res=
ort to that immediately.</div><div>At that point they now have compiler spe=
cific code and macros. If they had inline! in terms=C2=A0in the mentioned t=
hey would have less of that type of code.</div><div>My description of inlin=
e! if defined in terms of __forceinline and always_inline.</div><div><br></=
div><div>What you are after sounds like something more complicated and ther=
efore a=C2=A0different feature than what my suggestion is aiming for.</div>=
<div>I&#39;ve little doubt that what you want is of value but you are openi=
ng more cans of worms to get it.</div><div>A question to ask also is does y=
our feature likely promise to do the thing that=C2=A0makes people reach for=
=C2=A0__forceinline and always_inline.</div><div><br></div><div>I don&#39;t=
 really have much of a problem with anything you&#39;ve said other than I t=
hink if everyone heads off to define that what you are talking about I susp=
ect it&#39;ll be something else to what I&#39;m proposing.=C2=A0If it makes=
 C++ better, ok. It seems there are a few features in this space that peopl=
e need.</div></div></blockquote><div><br></div><div>What I&#39;m after is a=
 way to integrate force inlining into the language using the terms of the l=
anguage itself.</div><div>Inlining is an optimization, and like any other o=
ptimizations, it is outside the language.</div><div>You could say mandatory=
 RVO is an exception, but actually, this optimization is expressed within t=
he language itself, and not like an optimization (with prvalues and copy el=
ision).</div><div><br></div><div>If you want to integrate an optimization w=
ithin the language itself, it should makes something possible:</div><div>ma=
ndatory copy elision allows to return non-copyable, non moveable objects.</=
div><div>In case of forced inlining, it would allow to allocate objects in =
the caller scope.</div></div></blockquote><div><br></div><div>This is alrea=
dy available, and can be fully expressed in the language as is.=C2=A0</div>=
<div>Either by dependency injection or passing a reference to=C2=A0<font fa=
ce=3D"monospace, monospace">std::aligned_storage</font>, depending on when =
you want the constructor/destructor to fire.=C2=A0</div><div>Why someone wo=
uld want to express in which stack frame to store the object as <i><u>seman=
tic intent</u></i> is a mystery to me. It&#39;s an implementation detail (a=
s is the idea of a stack frame!). Therefore it is non-portable. Therefore i=
t has no place in the language.</div></div></div></blockquote><div><br></di=
v><div>No, in the implementation you propose the storage is allocated by ca=
ller, and passed to the callee. But the caller might not know how much the =
callee wants to allocate.</div><div><br></div><div>Also, I never talked abo=
ut stack frame, which are unknown to the language. I talked about scopes (w=
hich is in practice related to stack frames).</div><div>Scopes have 2 purpo=
ses: specifying which names are visibles, and specifying when objects are d=
estructed.</div><div>What I propose is to change the second point for inlin=
e! functions. This would be a semantic change, not just an implementation c=
hange.</div><div><br></div><div>The intent would be: the locals of an inlin=
e! function outlive the function call, and will be destroyed at the same ti=
me as the caller locals, ie: callee and caller locals are in the same scope=
..</div><div>I&#39;m pretty sure you could use it to avoid some dangling ref=
erences.<br></div></div></blockquote><div><br></div><div>This is already ex=
pressible:</div><div><br></div><div><div style=3D"color:rgb(0,0,0);backgrou=
nd-color:rgb(255,255,254)"><div><font face=3D"monospace, monospace"><span s=
tyle=3D"color:rgb(0,0,255)">#include</span><span style=3D"color:rgb(0,0,0)"=
> &lt;tuple&gt;</span></font></div><div><font face=3D"monospace, monospace"=
><span style=3D"color:rgb(0,0,255)">#include</span><span style=3D"color:rgb=
(0,0,0)"> &lt;string&gt;</span></font></div><font face=3D"monospace, monosp=
ace"><br></font><div><font face=3D"monospace, monospace"><span style=3D"col=
or:rgb(0,0,0)">std::tuple&lt;</span><span style=3D"color:rgb(0,0,255)">int<=
/span><span style=3D"color:rgb(0,0,0)">, std::string&gt; foo();</span></fon=
t></div><font face=3D"monospace, monospace"><br></font><div><span style=3D"=
color:rgb(0,0,0)"><font face=3D"monospace, monospace">std::size_t bar()</fo=
nt></span></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospa=
ce, monospace">{</font></span></div><div><font face=3D"monospace, monospace=
"><span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255)=
">=C2=A0 auto</span><span style=3D"color:rgb(0,0,0)">&amp;&amp; [ a, b ]  =
=3D foo();</span></font></div><div><font face=3D"monospace, monospace"><spa=
n style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255)">=C2=
=A0 return</span><span style=3D"color:rgb(0,0,0)"> a + b.size();=C2=A0 // a=
 and b outlive scope of foo()</span></font></div><div><span style=3D"color:=
rgb(0,0,0)"><font face=3D"monospace, monospace">}</font></span></div><br></=
div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/07767bd5-cd9f-4b9a-bee4-076ab043ccaa%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/07767bd5-cd9f-=
4b9a-bee4-076ab043ccaa%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hbvsBe6o-EW9%3DK%3D0NmvteuHphGO=
otYScrGEG8eMjYj8Kw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbvsBe6=
o-EW9%3DK%3D0NmvteuHphGOotYScrGEG8eMjYj8Kw%40mail.gmail.com</a>.<br />

--000000000000346b3d0570b9d8b9--

.


Author: florian.csdt@gmail.com
Date: Wed, 11 Jul 2018 07:29:10 -0700 (PDT)
Raw View
------=_Part_128606_854936511.1531319350762
Content-Type: multipart/alternative;
 boundary="----=_Part_128607_2110781348.1531319350763"

------=_Part_128607_2110781348.1531319350763
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mercredi 11 juillet 2018 16:13:04 UTC+2, Richard Hodges a =C3=A9crit :
>
>
>
> On Wed, 11 Jul 2018 at 15:54, <floria...@gmail.com <javascript:>> wrote:
>
>>
>>
>> Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9crit =
:
>>>
>>>
>>>
>>> On Wed, 11 Jul 2018 at 15:04, <floria...@gmail.com> wrote:
>>>
>>>>
>>>>
>>>> Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a =C3=A9=
crit :
>>>>>
>>>>>
>>>>>
>>>>> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.com=
=20
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> I would like to highlight some facts: the inline keyword is not=20
>>>>>> about inlining. As already said by others, the abstract machine has =
no=20
>>>>>> notion of what is inlining.
>>>>>> The reason is simple: inlining doesn't change the behavior of a=20
>>>>>> program, only its speed (and stack usage in some cases).
>>>>>> The abstract machine doesn't care about speed, only the bahavior.
>>>>>>
>>>>>
>>>>> I'm not sure keep thinking about inline on it's own is helpful to my=
=20
>>>>> case, though perhaps it might be for your case.
>>>>> But see my comment later.
>>>>>
>>>>> =20
>>>>>
>>>>>>
>>>>>> Currently, what inline is about is multiple definition of a single=
=20
>>>>>> function/object across translation units.
>>>>>> If you want extra information, have a look at=20
>>>>>> https://en.cppreference.com/w/cpp/language/inline=20
>>>>>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2F=
w%2Fcpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7uA=
N6nFcNoCw>
>>>>>>
>>>>>> That being said, it would still be interested to have a force inline=
..
>>>>>> The best example I can think of is calling alloca within a function,=
=20
>>>>>> and returning the pointer. On every compilers I tested, the allocate=
d stack=20
>>>>>> memory is kept after this call iif the call is actually inlined.
>>>>>> One use case would be runtime size class:
>>>>>> template class T>
>>>>>> class stack_array {
>>>>>>   private:
>>>>>>     T* p;
>>>>>>   public:
>>>>>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>>>>>     stack_array() =3D delete;
>>>>>>     stack_array(const stack_array&) =3D delete;
>>>>>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>>>>>     ~stack_array() =3D default;
>>>>>>
>>>>>>     /* ... */
>>>>>> };
>>>>>>
>>>>>> Now, to standardize that kind of stuff, I think we should speak in=
=20
>>>>>> terms of scopes:
>>>>>> the internal scope of an inline! function is the same as the scope=
=20
>>>>>> where the call is performed.
>>>>>> As the alloca memory is "deallocated" at the end of the scope, we=20
>>>>>> have the expected behavior.
>>>>>>
>>>>>> For this to work, the definition of the inline! function must be=20
>>>>>> visible at the call site, and the simplest way to implement it in th=
e=20
>>>>>> compiler is to actually perform inlining.
>>>>>> With such a definition, inline! cannot be implemented with an=20
>>>>>> attribute as it changes the semantic of the program, and cannot be i=
gnored.
>>>>>>
>>>>>
>>>>> People compile their code and when they don't get the result they=20
>>>>> want, they use __forceinline or always_inline or resort to that immed=
iately.
>>>>> At that point they now have compiler specific code and macros. If the=
y=20
>>>>> had inline! in terms in the mentioned they would have less of that ty=
pe of=20
>>>>> code.
>>>>> My description of inline! if defined in terms of __forceinline and=20
>>>>> always_inline.
>>>>>
>>>>> What you are after sounds like something more complicated and=20
>>>>> therefore a different feature than what my suggestion is aiming for.
>>>>> I've little doubt that what you want is of value but you are opening=
=20
>>>>> more cans of worms to get it.
>>>>> A question to ask also is does your feature likely promise to do the=
=20
>>>>> thing that makes people reach for __forceinline and always_inline.
>>>>>
>>>>> I don't really have much of a problem with anything you've said other=
=20
>>>>> than I think if everyone heads off to define that what you are talkin=
g=20
>>>>> about I suspect it'll be something else to what I'm proposing. If it =
makes=20
>>>>> C++ better, ok. It seems there are a few features in this space that =
people=20
>>>>> need.
>>>>>
>>>>
>>>> What I'm after is a way to integrate force inlining into the language=
=20
>>>> using the terms of the language itself.
>>>> Inlining is an optimization, and like any other optimizations, it is=
=20
>>>> outside the language.
>>>> You could say mandatory RVO is an exception, but actually, this=20
>>>> optimization is expressed within the language itself, and not like an=
=20
>>>> optimization (with prvalues and copy elision).
>>>>
>>>> If you want to integrate an optimization within the language itself, i=
t=20
>>>> should makes something possible:
>>>> mandatory copy elision allows to return non-copyable, non moveable=20
>>>> objects.
>>>> In case of forced inlining, it would allow to allocate objects in the=
=20
>>>> caller scope.
>>>>
>>>
>>> This is already available, and can be fully expressed in the language a=
s=20
>>> is.=20
>>> Either by dependency injection or passing a reference to=20
>>> std::aligned_storage, depending on when you want the=20
>>> constructor/destructor to fire.=20
>>> Why someone would want to express in which stack frame to store the=20
>>> object as *semantic intent* is a mystery to me. It's an implementation=
=20
>>> detail (as is the idea of a stack frame!). Therefore it is non-portable=
..=20
>>> Therefore it has no place in the language.
>>>
>>
>> No, in the implementation you propose the storage is allocated by caller=
,=20
>> and passed to the callee. But the caller might not know how much the cal=
lee=20
>> wants to allocate.
>>
>> Also, I never talked about stack frame, which are unknown to the=20
>> language. I talked about scopes (which is in practice related to stack=
=20
>> frames).
>> Scopes have 2 purposes: specifying which names are visibles, and=20
>> specifying when objects are destructed.
>> What I propose is to change the second point for inline! functions. This=
=20
>> would be a semantic change, not just an implementation change.
>>
>> The intent would be: the locals of an inline! function outlive the=20
>> function call, and will be destroyed at the same time as the caller loca=
ls,=20
>> ie: callee and caller locals are in the same scope.
>> I'm pretty sure you could use it to avoid some dangling references.
>>
>
> This is already expressible:
>
> #include <tuple>
> #include <string>
>
> std::tuple<int, std::string> foo();
>
> std::size_t bar()
> {
>   auto&& [ a, b ] =3D foo();
>   return a + b.size();  // a and b outlive scope of foo()
> }
>
>
>  True, that works, but it is the exact same problem as above: the caller=
=20
need to know the temporaries needed by the actual/useful return value from=
=20
the callee.
This is not about extending the lifetime of the return values, but extend=
=20
the lifetime of all locals, without the caller being aware.
Also, that doesn't work with alloca(). I'm not sure what C++ says about=20
alloca, though.

// create a safe buffer for C string manipulation with runtime size
inline! char* buffer(int n) {
  char* p =3D alloca(n+1); // +1 to be safe cannot be forgotten
  memset(p, n+1, 0);
  return p;
}

void foo(const char* s) {
  char* buf =3D buffer(strlen(s));
  /* do something with buf */
}

Here, the actual buffer returned by alloca cannot currently outlive the=20
call to buffer, and there is no easy way to do it.
How would you do that? Is your implementation easy to read/write/maintain?=
=20
The answer will probably be no.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f39dc947-2aa5-4471-a875-e55beaa62c71%40isocpp.or=
g.

------=_Part_128607_2110781348.1531319350763
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 16:13:04 UTC+2, Richar=
d Hodges a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, =
11 Jul 2018 at 15:54, &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"x1So--RoBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;">floria...@gmail.com</a>&gt; wrote:<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018=
 15:31:18 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div di=
r=3D"ltr">On Wed, 11 Jul 2018 at 15:04, &lt;<a rel=3D"nofollow">floria...@g=
mail.com</a>&gt; wrote:<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"><br><br>Le mercredi 11 juillet 2018 12:35:12 UTC+2, <a>gmis...@gmail.=
com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, <a>flori=
a...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);borde=
r-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><div><br></div><=
div>I would like to highlight some facts: the <span style=3D"font-family:co=
urier new,monospace">inline</span> keyword is not about inlining. As alread=
y said by others, the abstract machine has no notion of what is inlining.</=
div><div>The reason is simple: inlining doesn&#39;t change the behavior of =
a program, only its speed (and stack usage in some cases).</div><div>The ab=
stract machine doesn&#39;t care about speed, only the bahavior.</div></div>=
</blockquote><div><br></div><div>I&#39;m not sure keep thinking about inlin=
e on it&#39;s own is helpful to my case,=C2=A0though perhaps it might be fo=
r your case.</div><div>But see my comment later.</div><div><br></div><div>=
=C2=A0</div><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-left-style:solid"><div dir=3D"ltr"><div><br></div><div>Currently=
, what <span style=3D"font-family:courier new,monospace">inline</span> is a=
bout is multiple definition of a single function/object across translation =
units.<br></div><div>If you want extra information, have a look at <a href=
=3D"https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2Fw%2F=
cpp%2Flanguage%2Finline&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNGSULKdUyQcw=
ORlrV7uAN6nFcNoCw" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.h=
ref=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fen.cppreference.co=
m%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGSU=
LKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true;" onclick=3D"this.href=3D&#39;ht=
tps://www.google.com/url?q\x3dhttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2=
Flanguage%2Finline\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGSULKdUyQcwORlrV=
7uAN6nFcNoCw&#39;;return true;">https://en.cppreference.com/w/<wbr>cpp/lang=
uage/inline</a></div><div><br></div><div>That being said, it would still be=
 interested to have a force inline.</div><div>The best example I can think =
of is calling alloca within a function, and returning the pointer. On every=
 compilers I tested, the allocated stack memory is kept after this call iif=
 the call is actually inlined.</div><div>One use case would be runtime size=
 class:</div><div><div style=3D"border:1px solid rgb(187,187,187);backgroun=
d-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">tem=
plate</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> T</span><span st=
yle=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"><b=
r></span><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"colo=
r:rgb(0,0,0)"> stack_array </span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color=
:rgb(0,0,136)">private</span><span style=3D"color:rgb(102,102,0)">:</span><=
span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 T</span><span style=3D"co=
lor:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> p</span><span=
 style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><b=
r>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">public</span><span style=
=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">inline</span><span sty=
le=3D"color:rgb(102,102,0)">!</span><span style=3D"color:rgb(0,0,0)"> stack=
_array</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"co=
lor:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> n</span><span=
 style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb=
(0,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(0,0,0)">alloca</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style=3D"color:rgb(0,0,0)">n </span><span style=3D"color:rgb(102=
,102,0)">*</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(0,0,136)">sizeof</span><span style=3D"color:rgb(102,102,0)">(</span=
><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:rgb(102,102,=
0)">)))</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color=
:rgb(102,102,0)">{}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 stack_array</span><span style=3D"color:rgb(102,102,0)">()</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D<=
/span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0=
,136)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span styl=
e=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"c=
olor:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span=
><span style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:r=
gb(102,102,0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color=
:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0=
 stack_array</span><span style=3D"color:rgb(102,102,0)">&amp;</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">operat=
or</span><span style=3D"color:rgb(102,102,0)">=3D(</span><span style=3D"col=
or:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> stack_array<=
/span><span style=3D"color:rgb(102,102,0)">&amp;)</span><span style=3D"colo=
r:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">delet=
e</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)">~<=
/span><span style=3D"color:rgb(0,0,0)">stack_array</span><span style=3D"col=
or:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(0,0,136)">default</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(136,0,0)">/* ... */</span><span styl=
e=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};</=
span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></div><br>Now=
, to standardize that kind of stuff, I think we should speak in terms of sc=
opes:</div><div>the internal scope of an inline! function is the same as th=
e scope where the call is performed.</div><div>As the alloca memory is &quo=
t;deallocated&quot; at the end of the scope, we have the expected behavior.=
</div><div><br></div><div>For this to work, the definition of the inline! f=
unction must be visible at the call site, and the simplest way to implement=
 it in the compiler is to actually perform inlining.</div><div>With such a =
definition, inline! cannot be implemented with an attribute as it changes t=
he semantic of the program, and cannot be ignored.<br></div></div></blockqu=
ote><div><br></div><div>People compile their code and when they don&#39;t g=
et the result they want, they use __forceinline or=C2=A0always_inline or re=
sort to that immediately.</div><div>At that point they now have compiler sp=
ecific code and macros. If they had inline! in terms=C2=A0in the mentioned =
they would have less of that type of code.</div><div>My description of inli=
ne! if defined in terms of __forceinline and always_inline.</div><div><br><=
/div><div>What you are after sounds like something more complicated and the=
refore a=C2=A0different feature than what my suggestion is aiming for.</div=
><div>I&#39;ve little doubt that what you want is of value but you are open=
ing more cans of worms to get it.</div><div>A question to ask also is does =
your feature likely promise to do the thing that=C2=A0makes people reach fo=
r=C2=A0__forceinline and always_inline.</div><div><br></div><div>I don&#39;=
t really have much of a problem with anything you&#39;ve said other than I =
think if everyone heads off to define that what you are talking about I sus=
pect it&#39;ll be something else to what I&#39;m proposing.=C2=A0If it make=
s C++ better, ok. It seems there are a few features in this space that peop=
le need.</div></div></blockquote><div><br></div><div>What I&#39;m after is =
a way to integrate force inlining into the language using the terms of the =
language itself.</div><div>Inlining is an optimization, and like any other =
optimizations, it is outside the language.</div><div>You could say mandator=
y RVO is an exception, but actually, this optimization is expressed within =
the language itself, and not like an optimization (with prvalues and copy e=
lision).</div><div><br></div><div>If you want to integrate an optimization =
within the language itself, it should makes something possible:</div><div>m=
andatory copy elision allows to return non-copyable, non moveable objects.<=
/div><div>In case of forced inlining, it would allow to allocate objects in=
 the caller scope.</div></div></blockquote><div><br></div><div>This is alre=
ady available, and can be fully expressed in the language as is.=C2=A0</div=
><div>Either by dependency injection or passing a reference to=C2=A0<font f=
ace=3D"monospace, monospace">std::aligned_storage</font>, depending on when=
 you want the constructor/destructor to fire.=C2=A0</div><div>Why someone w=
ould want to express in which stack frame to store the object as <i><u>sema=
ntic intent</u></i> is a mystery to me. It&#39;s an implementation detail (=
as is the idea of a stack frame!). Therefore it is non-portable. Therefore =
it has no place in the language.</div></div></div></blockquote><div><br></d=
iv><div>No, in the implementation you propose the storage is allocated by c=
aller, and passed to the callee. But the caller might not know how much the=
 callee wants to allocate.</div><div><br></div><div>Also, I never talked ab=
out stack frame, which are unknown to the language. I talked about scopes (=
which is in practice related to stack frames).</div><div>Scopes have 2 purp=
oses: specifying which names are visibles, and specifying when objects are =
destructed.</div><div>What I propose is to change the second point for inli=
ne! functions. This would be a semantic change, not just an implementation =
change.</div><div><br></div><div>The intent would be: the locals of an inli=
ne! function outlive the function call, and will be destroyed at the same t=
ime as the caller locals, ie: callee and caller locals are in the same scop=
e.</div><div>I&#39;m pretty sure you could use it to avoid some dangling re=
ferences.<br></div></div></blockquote><div><br></div><div>This is already e=
xpressible:</div><div><br></div><div><div style=3D"color:rgb(0,0,0);backgro=
und-color:rgb(255,255,254)"><div><font face=3D"monospace, monospace"><span =
style=3D"color:rgb(0,0,255)">#include</span><span style=3D"color:rgb(0,0,0)=
"> &lt;tuple&gt;</span></font></div><div><font face=3D"monospace, monospace=
"><span style=3D"color:rgb(0,0,255)">#include</span><span style=3D"color:rg=
b(0,0,0)"> &lt;string&gt;</span></font></div><font face=3D"monospace, monos=
pace"><br></font><div><font face=3D"monospace, monospace"><span style=3D"co=
lor:rgb(0,0,0)">std::tuple&lt;</span><span style=3D"color:rgb(0,0,255)">int=
</span><span style=3D"color:rgb(0,0,0)">, std::string&gt; foo();</span></fo=
nt></div><font face=3D"monospace, monospace"><br></font><div><span style=3D=
"color:rgb(0,0,0)"><font face=3D"monospace, monospace">std::size_t bar()</f=
ont></span></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monosp=
ace, monospace">{</font></span></div><div><font face=3D"monospace, monospac=
e"><span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255=
)">=C2=A0 auto</span><span style=3D"color:rgb(0,0,0)">&amp;&amp; [ a, b ]  =
=3D foo();</span></font></div><div><font face=3D"monospace, monospace"><spa=
n style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255)">=C2=
=A0 return</span><span style=3D"color:rgb(0,0,0)"> a + b.size();=C2=A0 // a=
 and b outlive scope of foo()</span></font></div><div><span style=3D"color:=
rgb(0,0,0)"><font face=3D"monospace, monospace">}</font></span></div><br></=
div><br></div></div></div></blockquote><div>=C2=A0True, that works, but it =
is the exact same problem as above: the caller need to know the temporaries=
 needed by the actual/useful return value from the callee.</div><div>This i=
s not about extending the lifetime of the return values, but extend the lif=
etime of all locals, without the caller being aware.<br></div><div>Also, th=
at doesn&#39;t work with alloca(). I&#39;m not sure what C++ says about all=
oca, though.</div><div><br></div><div><div style=3D"background-color: rgb(2=
50, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; borde=
r-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// create a safe buffer for C string manipula=
tion with runtime size</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">inline</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">!</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> buffer</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> n</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">char</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> p </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> alloca</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">n</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">+</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">// +1 to be safe ca=
nnot be forgotten</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 memset</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">p</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> n</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 p</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">char</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">char</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> buf </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> buffer</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">strlen<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">/* do something with buf */</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></di=
v>Here, the actual buffer returned by alloca cannot currently outlive the c=
all to buffer, and there is no easy way to do it.</div><div>How would you d=
o that? Is your implementation easy to read/write/maintain? The answer will=
 probably be no.</div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f39dc947-2aa5-4471-a875-e55beaa62c71%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f39dc947-2aa5-4471-a875-e55beaa62c71=
%40isocpp.org</a>.<br />

------=_Part_128607_2110781348.1531319350763--

------=_Part_128606_854936511.1531319350762--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Wed, 11 Jul 2018 16:00:21 +0100
Raw View
--000000000000255e0b0570ba82ce
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 11 Jul 2018 at 15:29, <florian.csdt@gmail.com> wrote:

>
>
> Le mercredi 11 juillet 2018 16:13:04 UTC+2, Richard Hodges a =C3=A9crit :
>>
>>
>>
>> On Wed, 11 Jul 2018 at 15:54, <floria...@gmail.com> wrote:
>>
>>>
>>>
>>> Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9crit=
 :
>>>>
>>>>
>>>>
>>>> On Wed, 11 Jul 2018 at 15:04, <floria...@gmail.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a
>>>>> =C3=A9crit :
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12, floria...@gmail.co=
m
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>> I would like to highlight some facts: the inline keyword is not
>>>>>>> about inlining. As already said by others, the abstract machine has=
 no
>>>>>>> notion of what is inlining.
>>>>>>> The reason is simple: inlining doesn't change the behavior of a
>>>>>>> program, only its speed (and stack usage in some cases).
>>>>>>> The abstract machine doesn't care about speed, only the bahavior.
>>>>>>>
>>>>>>
>>>>>> I'm not sure keep thinking about inline on it's own is helpful to my
>>>>>> case, though perhaps it might be for your case.
>>>>>> But see my comment later.
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Currently, what inline is about is multiple definition of a single
>>>>>>> function/object across translation units.
>>>>>>> If you want extra information, have a look at
>>>>>>> https://en.cppreference.com/w/cpp/language/inline
>>>>>>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%2=
Fw%2Fcpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7u=
AN6nFcNoCw>
>>>>>>>
>>>>>>> That being said, it would still be interested to have a force inlin=
e.
>>>>>>> The best example I can think of is calling alloca within a function=
,
>>>>>>> and returning the pointer. On every compilers I tested, the allocat=
ed stack
>>>>>>> memory is kept after this call iif the call is actually inlined.
>>>>>>> One use case would be runtime size class:
>>>>>>> template class T>
>>>>>>> class stack_array {
>>>>>>>   private:
>>>>>>>     T* p;
>>>>>>>   public:
>>>>>>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>>>>>>     stack_array() =3D delete;
>>>>>>>     stack_array(const stack_array&) =3D delete;
>>>>>>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>>>>>>     ~stack_array() =3D default;
>>>>>>>
>>>>>>>     /* ... */
>>>>>>> };
>>>>>>>
>>>>>>> Now, to standardize that kind of stuff, I think we should speak in
>>>>>>> terms of scopes:
>>>>>>> the internal scope of an inline! function is the same as the scope
>>>>>>> where the call is performed.
>>>>>>> As the alloca memory is "deallocated" at the end of the scope, we
>>>>>>> have the expected behavior.
>>>>>>>
>>>>>>> For this to work, the definition of the inline! function must be
>>>>>>> visible at the call site, and the simplest way to implement it in t=
he
>>>>>>> compiler is to actually perform inlining.
>>>>>>> With such a definition, inline! cannot be implemented with an
>>>>>>> attribute as it changes the semantic of the program, and cannot be =
ignored.
>>>>>>>
>>>>>>
>>>>>> People compile their code and when they don't get the result they
>>>>>> want, they use __forceinline or always_inline or resort to that imme=
diately.
>>>>>> At that point they now have compiler specific code and macros. If
>>>>>> they had inline! in terms in the mentioned they would have less of t=
hat
>>>>>> type of code.
>>>>>> My description of inline! if defined in terms of __forceinline and
>>>>>> always_inline.
>>>>>>
>>>>>> What you are after sounds like something more complicated and
>>>>>> therefore a different feature than what my suggestion is aiming for.
>>>>>> I've little doubt that what you want is of value but you are opening
>>>>>> more cans of worms to get it.
>>>>>> A question to ask also is does your feature likely promise to do the
>>>>>> thing that makes people reach for __forceinline and always_inline.
>>>>>>
>>>>>> I don't really have much of a problem with anything you've said othe=
r
>>>>>> than I think if everyone heads off to define that what you are talki=
ng
>>>>>> about I suspect it'll be something else to what I'm proposing. If it=
 makes
>>>>>> C++ better, ok. It seems there are a few features in this space that=
 people
>>>>>> need.
>>>>>>
>>>>>
>>>>> What I'm after is a way to integrate force inlining into the language
>>>>> using the terms of the language itself.
>>>>> Inlining is an optimization, and like any other optimizations, it is
>>>>> outside the language.
>>>>> You could say mandatory RVO is an exception, but actually, this
>>>>> optimization is expressed within the language itself, and not like an
>>>>> optimization (with prvalues and copy elision).
>>>>>
>>>>> If you want to integrate an optimization within the language itself,
>>>>> it should makes something possible:
>>>>> mandatory copy elision allows to return non-copyable, non moveable
>>>>> objects.
>>>>> In case of forced inlining, it would allow to allocate objects in the
>>>>> caller scope.
>>>>>
>>>>
>>>> This is already available, and can be fully expressed in the language
>>>> as is.
>>>> Either by dependency injection or passing a reference to
>>>> std::aligned_storage, depending on when you want the
>>>> constructor/destructor to fire.
>>>> Why someone would want to express in which stack frame to store the
>>>> object as *semantic intent* is a mystery to me. It's an implementation
>>>> detail (as is the idea of a stack frame!). Therefore it is non-portabl=
e.
>>>> Therefore it has no place in the language.
>>>>
>>>
>>> No, in the implementation you propose the storage is allocated by
>>> caller, and passed to the callee. But the caller might not know how muc=
h
>>> the callee wants to allocate.
>>>
>>> Also, I never talked about stack frame, which are unknown to the
>>> language. I talked about scopes (which is in practice related to stack
>>> frames).
>>> Scopes have 2 purposes: specifying which names are visibles, and
>>> specifying when objects are destructed.
>>> What I propose is to change the second point for inline! functions. Thi=
s
>>> would be a semantic change, not just an implementation change.
>>>
>>> The intent would be: the locals of an inline! function outlive the
>>> function call, and will be destroyed at the same time as the caller loc=
als,
>>> ie: callee and caller locals are in the same scope.
>>> I'm pretty sure you could use it to avoid some dangling references.
>>>
>>
>> This is already expressible:
>>
>> #include <tuple>
>> #include <string>
>>
>> std::tuple<int, std::string> foo();
>>
>> std::size_t bar()
>> {
>>   auto&& [ a, b ] =3D foo();
>>   return a + b.size();  // a and b outlive scope of foo()
>> }
>>
>>
>>  True, that works, but it is the exact same problem as above: the caller
> need to know the temporaries needed by the actual/useful return value fro=
m
> the callee.
> This is not about extending the lifetime of the return values, but extend
> the lifetime of all locals, without the caller being aware.
> Also, that doesn't work with alloca(). I'm not sure what C++ says about
> alloca, though.
>
> // create a safe buffer for C string manipulation with runtime size
> inline! char* buffer(int n) {
>   char* p =3D alloca(n+1); // +1 to be safe cannot be forgotten
>   memset(p, n+1, 0);
>   return p;
> }
>
> void foo(const char* s) {
>   char* buf =3D buffer(strlen(s));
>   /* do something with buf */
> }
>
> Here, the actual buffer returned by alloca cannot currently outlive the
> call to buffer, and there is no easy way to do it.
> How would you do that? Is your implementation easy to read/write/maintain=
?
> The answer will probably be no.
>

alloca() is not supported in c++. In this kind of scenario you should
return a copy of an object and allow the optimiser to do its job, or
use a static
thread_local buffer.

Why on earth do you want to return a naked pointer to stack space?



>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f39dc947-2aa=
5-4471-a875-e55beaa62c71%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f39dc947-2a=
a5-4471-a875-e55beaa62c71%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hav-s7eB2-YBvfi15gp1VHTs3KbH16Hy77HbNmYsj-=
0DQ%40mail.gmail.com.

--000000000000255e0b0570ba82ce
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, 11 Jul 2018 at 15:29, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 16:13:04 UTC+2, Richard =
Hodges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, 11 Jul=
 2018 at 15:54, &lt;<a rel=3D"nofollow">floria...@gmail.com</a>&gt; wrote:<=
br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le mercred=
i 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br><div class=3D"gma=
il_quote"><div dir=3D"ltr">On Wed, 11 Jul 2018 at 15:04, &lt;<a rel=3D"nofo=
llow">floria...@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 12:35:12 UTC+2, =
<a>gmis...@gmail.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 8:23:51 PM=
 UTC+12, <a>floria...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(2=
04,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"=
><div><br></div><div>I would like to highlight some facts: the <span style=
=3D"font-family:courier new,monospace">inline</span> keyword is not about i=
nlining. As already said by others, the abstract machine has no notion of w=
hat is inlining.</div><div>The reason is simple: inlining doesn&#39;t chang=
e the behavior of a program, only its speed (and stack usage in some cases)=
..</div><div>The abstract machine doesn&#39;t care about speed, only the bah=
avior.</div></div></blockquote><div><br></div><div>I&#39;m not sure keep th=
inking about inline on it&#39;s own is helpful to my case,=C2=A0though perh=
aps it might be for your case.</div><div>But see my comment later.</div><di=
v><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);b=
order-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><div><br></d=
iv><div>Currently, what <span style=3D"font-family:courier new,monospace">i=
nline</span> is about is multiple definition of a single function/object ac=
ross translation units.<br></div><div>If you want extra information, have a=
 look at <a href=3D"https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cpprefe=
rence.com%2Fw%2Fcpp%2Flanguage%2Finline&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DA=
FQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw" rel=3D"nofollow" target=3D"_blank">https=
://en.cppreference.com/w/cpp/language/inline</a></div><div><br></div><div>T=
hat being said, it would still be interested to have a force inline.</div><=
div>The best example I can think of is calling alloca within a function, an=
d returning the pointer. On every compilers I tested, the allocated stack m=
emory is kept after this call iif the call is actually inlined.</div><div>O=
ne use case would be runtime size class:</div><div><div style=3D"border:1px=
 solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><span=
 style=3D"color:rgb(0,0,136)">template</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"co=
lor:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><s=
pan style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)=
">class</span><span style=3D"color:rgb(0,0,0)"> stack_array </span><span st=
yle=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">private</span><span style=
=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 T</span><span style=3D"color:rgb(102,102,0)">*</span><span style=
=3D"color:rgb(0,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">;</span=
><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rg=
b(0,0,136)">public</span><span style=3D"color:rgb(102,102,0)">:</span><span=
 style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:r=
gb(0,0,136)">inline</span><span style=3D"color:rgb(102,102,0)">!</span><spa=
n style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style=3D"color:rgb(0,0,136)">int</span><span style=
=3D"color:rgb(0,0,0)"> n</span><span style=3D"color:rgb(102,102,0)">)</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,=
0)">:</span><span style=3D"color:rgb(0,0,0)"> p</span><span style=3D"color:=
rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">alloca</span><span=
 style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">n =
</span><span style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">sizeof</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">T</spa=
n><span style=3D"color:rgb(102,102,0)">)))</span><span style=3D"color:rgb(0=
,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{}</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:r=
gb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 s=
tack_array</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> stack=
_array</span><span style=3D"color:rgb(102,102,0)">&amp;)</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">&amp;</span><span style=3D"color:rgb(0,0,0)"> </span><span=
 style=3D"color:rgb(0,0,136)">operator</span><span style=3D"color:rgb(102,1=
02,0)">=3D(</span><span style=3D"color:rgb(0,0,136)">const</span><span styl=
e=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(102,102,=
0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:rgb(102,10=
2,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:rgb(102,102,0)">~</span><span style=3D"color:rgb(0,0,0)">=
stack_array</span><span style=3D"color:rgb(102,102,0)">()</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">default</span><span style=3D"color:rgb(102,102,0)">;</span><span style=
=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb=
(136,0,0)">/* ... */</span><span style=3D"color:rgb(0,0,0)"><br></span><spa=
n style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)">=
<br></span></div></code></div><br>Now, to standardize that kind of stuff, I=
 think we should speak in terms of scopes:</div><div>the internal scope of =
an inline! function is the same as the scope where the call is performed.</=
div><div>As the alloca memory is &quot;deallocated&quot; at the end of the =
scope, we have the expected behavior.</div><div><br></div><div>For this to =
work, the definition of the inline! function must be visible at the call si=
te, and the simplest way to implement it in the compiler is to actually per=
form inlining.</div><div>With such a definition, inline! cannot be implemen=
ted with an attribute as it changes the semantic of the program, and cannot=
 be ignored.<br></div></div></blockquote><div><br></div><div>People compile=
 their code and when they don&#39;t get the result they want, they use __fo=
rceinline or=C2=A0always_inline or resort to that immediately.</div><div>At=
 that point they now have compiler specific code and macros. If they had in=
line! in terms=C2=A0in the mentioned they would have less of that type of c=
ode.</div><div>My description of inline! if defined in terms of __forceinli=
ne and always_inline.</div><div><br></div><div>What you are after sounds li=
ke something more complicated and therefore a=C2=A0different feature than w=
hat my suggestion is aiming for.</div><div>I&#39;ve little doubt that what =
you want is of value but you are opening more cans of worms to get it.</div=
><div>A question to ask also is does your feature likely promise to do the =
thing that=C2=A0makes people reach for=C2=A0__forceinline and always_inline=
..</div><div><br></div><div>I don&#39;t really have much of a problem with a=
nything you&#39;ve said other than I think if everyone heads off to define =
that what you are talking about I suspect it&#39;ll be something else to wh=
at I&#39;m proposing.=C2=A0If it makes C++ better, ok. It seems there are a=
 few features in this space that people need.</div></div></blockquote><div>=
<br></div><div>What I&#39;m after is a way to integrate force inlining into=
 the language using the terms of the language itself.</div><div>Inlining is=
 an optimization, and like any other optimizations, it is outside the langu=
age.</div><div>You could say mandatory RVO is an exception, but actually, t=
his optimization is expressed within the language itself, and not like an o=
ptimization (with prvalues and copy elision).</div><div><br></div><div>If y=
ou want to integrate an optimization within the language itself, it should =
makes something possible:</div><div>mandatory copy elision allows to return=
 non-copyable, non moveable objects.</div><div>In case of forced inlining, =
it would allow to allocate objects in the caller scope.</div></div></blockq=
uote><div><br></div><div>This is already available, and can be fully expres=
sed in the language as is.=C2=A0</div><div>Either by dependency injection o=
r passing a reference to=C2=A0<font face=3D"monospace, monospace">std::alig=
ned_storage</font>, depending on when you want the constructor/destructor t=
o fire.=C2=A0</div><div>Why someone would want to express in which stack fr=
ame to store the object as <i><u>semantic intent</u></i> is a mystery to me=
.. It&#39;s an implementation detail (as is the idea of a stack frame!). The=
refore it is non-portable. Therefore it has no place in the language.</div>=
</div></div></blockquote><div><br></div><div>No, in the implementation you =
propose the storage is allocated by caller, and passed to the callee. But t=
he caller might not know how much the callee wants to allocate.</div><div><=
br></div><div>Also, I never talked about stack frame, which are unknown to =
the language. I talked about scopes (which is in practice related to stack =
frames).</div><div>Scopes have 2 purposes: specifying which names are visib=
les, and specifying when objects are destructed.</div><div>What I propose i=
s to change the second point for inline! functions. This would be a semanti=
c change, not just an implementation change.</div><div><br></div><div>The i=
ntent would be: the locals of an inline! function outlive the function call=
, and will be destroyed at the same time as the caller locals, ie: callee a=
nd caller locals are in the same scope.</div><div>I&#39;m pretty sure you c=
ould use it to avoid some dangling references.<br></div></div></blockquote>=
<div><br></div><div>This is already expressible:</div><div><br></div><div><=
div style=3D"color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><font=
 face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,255)">#include<=
/span><span style=3D"color:rgb(0,0,0)"> &lt;tuple&gt;</span></font></div><d=
iv><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,255)">#=
include</span><span style=3D"color:rgb(0,0,0)"> &lt;string&gt;</span></font=
></div><font face=3D"monospace, monospace"><br></font><div><font face=3D"mo=
nospace, monospace"><span style=3D"color:rgb(0,0,0)">std::tuple&lt;</span><=
span style=3D"color:rgb(0,0,255)">int</span><span style=3D"color:rgb(0,0,0)=
">, std::string&gt; foo();</span></font></div><font face=3D"monospace, mono=
space"><br></font><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monos=
pace, monospace">std::size_t bar()</font></span></div><div><span style=3D"c=
olor:rgb(0,0,0)"><font face=3D"monospace, monospace">{</font></span></div><=
div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></=
span><span style=3D"color:rgb(0,0,255)">=C2=A0 auto</span><span style=3D"co=
lor:rgb(0,0,0)">&amp;&amp; [ a, b ]  =3D foo();</span></font></div><div><fo=
nt face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></span><s=
pan style=3D"color:rgb(0,0,255)">=C2=A0 return</span><span style=3D"color:r=
gb(0,0,0)"> a + b.size();=C2=A0 // a and b outlive scope of foo()</span></f=
ont></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, mo=
nospace">}</font></span></div><br></div><br></div></div></div></blockquote>=
<div>=C2=A0True, that works, but it is the exact same problem as above: the=
 caller need to know the temporaries needed by the actual/useful return val=
ue from the callee.</div><div>This is not about extending the lifetime of t=
he return values, but extend the lifetime of all locals, without the caller=
 being aware.<br></div><div>Also, that doesn&#39;t work with alloca(). I&#3=
9;m not sure what C++ says about alloca, though.</div><div><br></div><div><=
div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187=
);border-style:solid;border-width:1px" class=3D"m_2960374536371148831pretty=
print"><code class=3D"m_2960374536371148831prettyprint"><div class=3D"m_296=
0374536371148831subprettyprint"><span style=3D"color:#800" class=3D"m_29603=
74536371148831styled-by-prettify">// create a safe buffer for C string mani=
pulation with runtime size</span><span style=3D"color:#000" class=3D"m_2960=
374536371148831styled-by-prettify"><br></span><span style=3D"color:#008" cl=
ass=3D"m_2960374536371148831styled-by-prettify">inline</span><span style=3D=
"color:#660" class=3D"m_2960374536371148831styled-by-prettify">!</span><spa=
n style=3D"color:#000" class=3D"m_2960374536371148831styled-by-prettify"> <=
/span><span style=3D"color:#008" class=3D"m_2960374536371148831styled-by-pr=
ettify">char</span><span style=3D"color:#660" class=3D"m_296037453637114883=
1styled-by-prettify">*</span><span style=3D"color:#000" class=3D"m_29603745=
36371148831styled-by-prettify"> buffer</span><span style=3D"color:#660" cla=
ss=3D"m_2960374536371148831styled-by-prettify">(</span><span style=3D"color=
:#008" class=3D"m_2960374536371148831styled-by-prettify">int</span><span st=
yle=3D"color:#000" class=3D"m_2960374536371148831styled-by-prettify"> n</sp=
an><span style=3D"color:#660" class=3D"m_2960374536371148831styled-by-prett=
ify">)</span><span style=3D"color:#000" class=3D"m_2960374536371148831style=
d-by-prettify"> </span><span style=3D"color:#660" class=3D"m_29603745363711=
48831styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_2960=
374536371148831styled-by-prettify"><br>=C2=A0 </span><span style=3D"color:#=
008" class=3D"m_2960374536371148831styled-by-prettify">char</span><span sty=
le=3D"color:#660" class=3D"m_2960374536371148831styled-by-prettify">*</span=
><span style=3D"color:#000" class=3D"m_2960374536371148831styled-by-prettif=
y"> p </span><span style=3D"color:#660" class=3D"m_2960374536371148831style=
d-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_296037453637=
1148831styled-by-prettify"> alloca</span><span style=3D"color:#660" class=
=3D"m_2960374536371148831styled-by-prettify">(</span><span style=3D"color:#=
000" class=3D"m_2960374536371148831styled-by-prettify">n</span><span style=
=3D"color:#660" class=3D"m_2960374536371148831styled-by-prettify">+</span><=
span style=3D"color:#066" class=3D"m_2960374536371148831styled-by-prettify"=
>1</span><span style=3D"color:#660" class=3D"m_2960374536371148831styled-by=
-prettify">);</span><span style=3D"color:#000" class=3D"m_29603745363711488=
31styled-by-prettify"> </span><span style=3D"color:#800" class=3D"m_2960374=
536371148831styled-by-prettify">// +1 to be safe cannot be forgotten</span>=
<span style=3D"color:#000" class=3D"m_2960374536371148831styled-by-prettify=
"><br>=C2=A0 memset</span><span style=3D"color:#660" class=3D"m_29603745363=
71148831styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_2=
960374536371148831styled-by-prettify">p</span><span style=3D"color:#660" cl=
ass=3D"m_2960374536371148831styled-by-prettify">,</span><span style=3D"colo=
r:#000" class=3D"m_2960374536371148831styled-by-prettify"> n</span><span st=
yle=3D"color:#660" class=3D"m_2960374536371148831styled-by-prettify">+</spa=
n><span style=3D"color:#066" class=3D"m_2960374536371148831styled-by-pretti=
fy">1</span><span style=3D"color:#660" class=3D"m_2960374536371148831styled=
-by-prettify">,</span><span style=3D"color:#000" class=3D"m_296037453637114=
8831styled-by-prettify"> </span><span style=3D"color:#066" class=3D"m_29603=
74536371148831styled-by-prettify">0</span><span style=3D"color:#660" class=
=3D"m_2960374536371148831styled-by-prettify">);</span><span style=3D"color:=
#000" class=3D"m_2960374536371148831styled-by-prettify"><br>=C2=A0 </span><=
span style=3D"color:#008" class=3D"m_2960374536371148831styled-by-prettify"=
>return</span><span style=3D"color:#000" class=3D"m_2960374536371148831styl=
ed-by-prettify"> p</span><span style=3D"color:#660" class=3D"m_296037453637=
1148831styled-by-prettify">;</span><span style=3D"color:#000" class=3D"m_29=
60374536371148831styled-by-prettify"><br></span><span style=3D"color:#660" =
class=3D"m_2960374536371148831styled-by-prettify">}</span><span style=3D"co=
lor:#000" class=3D"m_2960374536371148831styled-by-prettify"><br><br></span>=
<span style=3D"color:#008" class=3D"m_2960374536371148831styled-by-prettify=
">void</span><span style=3D"color:#000" class=3D"m_2960374536371148831style=
d-by-prettify"> foo</span><span style=3D"color:#660" class=3D"m_29603745363=
71148831styled-by-prettify">(</span><span style=3D"color:#008" class=3D"m_2=
960374536371148831styled-by-prettify">const</span><span style=3D"color:#000=
" class=3D"m_2960374536371148831styled-by-prettify"> </span><span style=3D"=
color:#008" class=3D"m_2960374536371148831styled-by-prettify">char</span><s=
pan style=3D"color:#660" class=3D"m_2960374536371148831styled-by-prettify">=
*</span><span style=3D"color:#000" class=3D"m_2960374536371148831styled-by-=
prettify"> s</span><span style=3D"color:#660" class=3D"m_296037453637114883=
1styled-by-prettify">)</span><span style=3D"color:#000" class=3D"m_29603745=
36371148831styled-by-prettify"> </span><span style=3D"color:#660" class=3D"=
m_2960374536371148831styled-by-prettify">{</span><span style=3D"color:#000"=
 class=3D"m_2960374536371148831styled-by-prettify"><br>=C2=A0 </span><span =
style=3D"color:#008" class=3D"m_2960374536371148831styled-by-prettify">char=
</span><span style=3D"color:#660" class=3D"m_2960374536371148831styled-by-p=
rettify">*</span><span style=3D"color:#000" class=3D"m_2960374536371148831s=
tyled-by-prettify"> buf </span><span style=3D"color:#660" class=3D"m_296037=
4536371148831styled-by-prettify">=3D</span><span style=3D"color:#000" class=
=3D"m_2960374536371148831styled-by-prettify"> buffer</span><span style=3D"c=
olor:#660" class=3D"m_2960374536371148831styled-by-prettify">(</span><span =
style=3D"color:#000" class=3D"m_2960374536371148831styled-by-prettify">strl=
en</span><span style=3D"color:#660" class=3D"m_2960374536371148831styled-by=
-prettify">(</span><span style=3D"color:#000" class=3D"m_296037453637114883=
1styled-by-prettify">s</span><span style=3D"color:#660" class=3D"m_29603745=
36371148831styled-by-prettify">));</span><span style=3D"color:#000" class=
=3D"m_2960374536371148831styled-by-prettify"><br>=C2=A0 </span><span style=
=3D"color:#800" class=3D"m_2960374536371148831styled-by-prettify">/* do som=
ething with buf */</span><span style=3D"color:#000" class=3D"m_296037453637=
1148831styled-by-prettify"><br></span><span style=3D"color:#660" class=3D"m=
_2960374536371148831styled-by-prettify">}</span><span style=3D"color:#000" =
class=3D"m_2960374536371148831styled-by-prettify"><br><br></span></div></co=
de></div>Here, the actual buffer returned by alloca cannot currently outliv=
e the call to buffer, and there is no easy way to do it.</div><div>How woul=
d you do that? Is your implementation easy to read/write/maintain? The answ=
er will probably be no.</div></div></blockquote><div><br></div><div>alloca(=
) is not supported in c++. In this kind of scenario you should return a cop=
y of an object and allow the optimiser to do its job, or use a <font face=
=3D"monospace, monospace">static thread_local </font>buffer.</div><div><br>=
</div><div>Why on earth do you want to return a naked pointer to stack spac=
e?</div><div><br></div><div>=C2=A0<br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div><br></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f39dc947-2aa5-4471-a875-e55beaa62c71%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f39dc947-2aa5-=
4471-a875-e55beaa62c71%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hav-s7eB2-YBvfi15gp1VHTs3KbH16H=
y77HbNmYsj-0DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hav-s7eB2-Y=
Bvfi15gp1VHTs3KbH16Hy77HbNmYsj-0DQ%40mail.gmail.com</a>.<br />

--000000000000255e0b0570ba82ce--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Jul 2018 08:06:37 -0700 (PDT)
Raw View
------=_Part_128503_36586867.1531321598022
Content-Type: multipart/alternative;
 boundary="----=_Part_128504_1039236780.1531321598022"

------=_Part_128504_1039236780.1531321598022
Content-Type: text/plain; charset="UTF-8"

On Wednesday, July 11, 2018 at 9:54:03 AM UTC-4, floria...@gmail.com wrote:
>
> No, in the implementation you propose the storage is allocated by caller,
> and passed to the callee. But the caller might not know how much the callee
> wants to allocate.
>
> Also, I never talked about stack frame, which are unknown to the language.
> I talked about scopes (which is in practice related to stack frames).
> Scopes have 2 purposes: specifying which names are visibles, and
> specifying when objects are destructed.
> What I propose is to change the second point for inline! functions. This
> would be a semantic change, not just an implementation change.
>
> The intent would be: the locals of an inline! function outlive the
> function call, and will be destroyed at the same time as the caller locals,
> ie: callee and caller locals are in the same scope.
> I'm pretty sure you could use it to avoid some dangling references.
>

But what you're talking about isn't really a function anymore. If the
object still exists but has no name... what exactly is the point of it?
Unless the function stored a pointer/reference to these objects somewhere
that the outer scope can access it, why do those objects need to exist?

And if it could do that, why not just let the names be accessible too? If
we're relying on the existence of some objects, then rely on it already.
And if we're going that far, why not allow the `inline!` function be able
to return *for* its caller rather than *to* its caller? Or affect its
caller in other ways.

You can see that we're quickly moving away from being a mere "function" and
becoming something else: a named series of statements that get copy-pasted
into code. That might be a useful feature or a confusing one. But this
half-state between them that you propose is exactly that: a half-state.
Neither one thing nor the other, the construct is only useful in a trivial
number of instances.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc55cf7b-1f3d-4b2a-97d1-620835b8b069%40isocpp.org.

------=_Part_128504_1039236780.1531321598022
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, July 11, 2018 at 9:54:03 AM UTC-4, floria...=
@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div></div><div>No, in the implementation you propose the storage is al=
located by caller, and passed to the callee. But the caller might not know =
how much the callee wants to allocate.</div><div><br></div><div>Also, I nev=
er talked about stack frame, which are unknown to the language. I talked ab=
out scopes (which is in practice related to stack frames).</div><div>Scopes=
 have 2 purposes: specifying which names are visibles, and specifying when =
objects are destructed.</div><div>What I propose is to change the second po=
int for inline! functions. This would be a semantic change, not just an imp=
lementation change.</div><div><br></div><div>The intent would be: the local=
s of an inline! function outlive the function call, and will be destroyed a=
t the same time as the caller locals, ie: callee and caller locals are in t=
he same scope.</div><div>I&#39;m pretty sure you could use it to avoid some=
 dangling references.<br></div></div></blockquote><div><br></div><div>But w=
hat you&#39;re talking about isn&#39;t really a function anymore. If the ob=
ject still exists but has no name... what exactly is the point of it? Unles=
s the function stored a pointer/reference to these objects somewhere that t=
he outer scope can access it, why do those objects need to exist?<br></div>=
<div><br></div><div>And if it could do that, why not just let the names be =
accessible too? If we&#39;re relying on the existence of some objects, then=
 rely on it already. And if we&#39;re going that far, why not allow the `in=
line!` function be able to return <i>for</i> its caller rather than <i>to</=
i> its caller? Or affect its caller in other ways.</div><div><br></div><div=
>You can see that we&#39;re quickly moving away from being a mere &quot;fun=
ction&quot; and becoming something else: a named series of statements that =
get copy-pasted into code. That might be a useful feature or a confusing on=
e. But this half-state between them that you propose is exactly that: a hal=
f-state. Neither one thing nor the other, the construct is only useful in a=
 trivial number of instances.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cc55cf7b-1f3d-4b2a-97d1-620835b8b069%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cc55cf7b-1f3d-4b2a-97d1-620835b8b069=
%40isocpp.org</a>.<br />

------=_Part_128504_1039236780.1531321598022--

------=_Part_128503_36586867.1531321598022--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Jul 2018 08:10:10 -0700 (PDT)
Raw View
------=_Part_128366_1671436022.1531321810448
Content-Type: multipart/alternative;
 boundary="----=_Part_128367_2065229132.1531321810449"

------=_Part_128367_2065229132.1531321810449
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Wednesday, July 11, 2018 at 11:00:35 AM UTC-4, Richard Hodges wrote:
>
>
>
> On Wed, 11 Jul 2018 at 15:29, <floria...@gmail.com <javascript:>> wrote:
>
>>
>>
>> Le mercredi 11 juillet 2018 16:13:04 UTC+2, Richard Hodges a =C3=A9crit =
:
>>>
>>>
>>>
>>> On Wed, 11 Jul 2018 at 15:54, <floria...@gmail.com> wrote:
>>>
>>>>
>>>>
>>>> Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9cri=
t :
>>>>>
>>>>>
>>>>>
>>>>> On Wed, 11 Jul 2018 at 15:04, <floria...@gmail.com> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> Le mercredi 11 juillet 2018 12:35:12 UTC+2, gmis...@gmail.com a=20
>>>>>> =C3=A9crit :
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wednesday, July 11, 2018 at 8:23:51 PM UTC+12,=20
>>>>>>> floria...@gmail.com wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> I would like to highlight some facts: the inline keyword is not=20
>>>>>>>> about inlining. As already said by others, the abstract machine ha=
s no=20
>>>>>>>> notion of what is inlining.
>>>>>>>> The reason is simple: inlining doesn't change the behavior of a=20
>>>>>>>> program, only its speed (and stack usage in some cases).
>>>>>>>> The abstract machine doesn't care about speed, only the bahavior.
>>>>>>>>
>>>>>>>
>>>>>>> I'm not sure keep thinking about inline on it's own is helpful to m=
y=20
>>>>>>> case, though perhaps it might be for your case.
>>>>>>> But see my comment later.
>>>>>>>
>>>>>>> =20
>>>>>>>
>>>>>>>>
>>>>>>>> Currently, what inline is about is multiple definition of a single=
=20
>>>>>>>> function/object across translation units.
>>>>>>>> If you want extra information, have a look at=20
>>>>>>>> https://en.cppreference.com/w/cpp/language/inline=20
>>>>>>>> <https://www.google.com/url?q=3Dhttps%3A%2F%2Fen.cppreference.com%=
2Fw%2Fcpp%2Flanguage%2Finline&sa=3DD&sntz=3D1&usg=3DAFQjCNGSULKdUyQcwORlrV7=
uAN6nFcNoCw>
>>>>>>>>
>>>>>>>> That being said, it would still be interested to have a force=20
>>>>>>>> inline.
>>>>>>>> The best example I can think of is calling alloca within a=20
>>>>>>>> function, and returning the pointer. On every compilers I tested, =
the=20
>>>>>>>> allocated stack memory is kept after this call iif the call is act=
ually=20
>>>>>>>> inlined.
>>>>>>>> One use case would be runtime size class:
>>>>>>>> template class T>
>>>>>>>> class stack_array {
>>>>>>>>   private:
>>>>>>>>     T* p;
>>>>>>>>   public:
>>>>>>>>     inline! stack_array(int n) : p(alloca(n * sizeof(T))) {}
>>>>>>>>     stack_array() =3D delete;
>>>>>>>>     stack_array(const stack_array&) =3D delete;
>>>>>>>>     stack_array& operator=3D(const stack_array&) =3D delete;
>>>>>>>>     ~stack_array() =3D default;
>>>>>>>>
>>>>>>>>     /* ... */
>>>>>>>> };
>>>>>>>>
>>>>>>>> Now, to standardize that kind of stuff, I think we should speak in=
=20
>>>>>>>> terms of scopes:
>>>>>>>> the internal scope of an inline! function is the same as the scope=
=20
>>>>>>>> where the call is performed.
>>>>>>>> As the alloca memory is "deallocated" at the end of the scope, we=
=20
>>>>>>>> have the expected behavior.
>>>>>>>>
>>>>>>>> For this to work, the definition of the inline! function must be=
=20
>>>>>>>> visible at the call site, and the simplest way to implement it in =
the=20
>>>>>>>> compiler is to actually perform inlining.
>>>>>>>> With such a definition, inline! cannot be implemented with an=20
>>>>>>>> attribute as it changes the semantic of the program, and cannot be=
 ignored.
>>>>>>>>
>>>>>>>
>>>>>>> People compile their code and when they don't get the result they=
=20
>>>>>>> want, they use __forceinline or always_inline or resort to that imm=
ediately.
>>>>>>> At that point they now have compiler specific code and macros. If=
=20
>>>>>>> they had inline! in terms in the mentioned they would have less of =
that=20
>>>>>>> type of code.
>>>>>>> My description of inline! if defined in terms of __forceinline and=
=20
>>>>>>> always_inline.
>>>>>>>
>>>>>>> What you are after sounds like something more complicated and=20
>>>>>>> therefore a different feature than what my suggestion is aiming for=
..
>>>>>>> I've little doubt that what you want is of value but you are openin=
g=20
>>>>>>> more cans of worms to get it.
>>>>>>> A question to ask also is does your feature likely promise to do th=
e=20
>>>>>>> thing that makes people reach for __forceinline and always_inline.
>>>>>>>
>>>>>>> I don't really have much of a problem with anything you've said=20
>>>>>>> other than I think if everyone heads off to define that what you ar=
e=20
>>>>>>> talking about I suspect it'll be something else to what I'm proposi=
ng. If=20
>>>>>>> it makes C++ better, ok. It seems there are a few features in this =
space=20
>>>>>>> that people need.
>>>>>>>
>>>>>>
>>>>>> What I'm after is a way to integrate force inlining into the languag=
e=20
>>>>>> using the terms of the language itself.
>>>>>> Inlining is an optimization, and like any other optimizations, it is=
=20
>>>>>> outside the language.
>>>>>> You could say mandatory RVO is an exception, but actually, this=20
>>>>>> optimization is expressed within the language itself, and not like a=
n=20
>>>>>> optimization (with prvalues and copy elision).
>>>>>>
>>>>>> If you want to integrate an optimization within the language itself,=
=20
>>>>>> it should makes something possible:
>>>>>> mandatory copy elision allows to return non-copyable, non moveable=
=20
>>>>>> objects.
>>>>>> In case of forced inlining, it would allow to allocate objects in th=
e=20
>>>>>> caller scope.
>>>>>>
>>>>>
>>>>> This is already available, and can be fully expressed in the language=
=20
>>>>> as is.=20
>>>>> Either by dependency injection or passing a reference to=20
>>>>> std::aligned_storage, depending on when you want the=20
>>>>> constructor/destructor to fire.=20
>>>>> Why someone would want to express in which stack frame to store the=
=20
>>>>> object as *semantic intent* is a mystery to me. It's an=20
>>>>> implementation detail (as is the idea of a stack frame!). Therefore i=
t is=20
>>>>> non-portable. Therefore it has no place in the language.
>>>>>
>>>>
>>>> No, in the implementation you propose the storage is allocated by=20
>>>> caller, and passed to the callee. But the caller might not know how mu=
ch=20
>>>> the callee wants to allocate.
>>>>
>>>> Also, I never talked about stack frame, which are unknown to the=20
>>>> language. I talked about scopes (which is in practice related to stack=
=20
>>>> frames).
>>>> Scopes have 2 purposes: specifying which names are visibles, and=20
>>>> specifying when objects are destructed.
>>>> What I propose is to change the second point for inline! functions.=20
>>>> This would be a semantic change, not just an implementation change.
>>>>
>>>> The intent would be: the locals of an inline! function outlive the=20
>>>> function call, and will be destroyed at the same time as the caller lo=
cals,=20
>>>> ie: callee and caller locals are in the same scope.
>>>> I'm pretty sure you could use it to avoid some dangling references.
>>>>
>>>
>>> This is already expressible:
>>>
>>> #include <tuple>
>>> #include <string>
>>>
>>> std::tuple<int, std::string> foo();
>>>
>>> std::size_t bar()
>>> {
>>>   auto&& [ a, b ] =3D foo();
>>>   return a + b.size();  // a and b outlive scope of foo()
>>> }
>>>
>>>
>>>  True, that works, but it is the exact same problem as above: the calle=
r=20
>> need to know the temporaries needed by the actual/useful return value fr=
om=20
>> the callee.
>> This is not about extending the lifetime of the return values, but exten=
d=20
>> the lifetime of all locals, without the caller being aware.
>> Also, that doesn't work with alloca(). I'm not sure what C++ says about=
=20
>> alloca, though.
>>
>> // create a safe buffer for C string manipulation with runtime size
>> inline! char* buffer(int n) {
>>   char* p =3D alloca(n+1); // +1 to be safe cannot be forgotten
>>   memset(p, n+1, 0);
>>   return p;
>> }
>>
>> void foo(const char* s) {
>>   char* buf =3D buffer(strlen(s));
>>   /* do something with buf */
>> }
>>
>> Here, the actual buffer returned by alloca cannot currently outlive the=
=20
>> call to buffer, and there is no easy way to do it.
>> How would you do that? Is your implementation easy to=20
>> read/write/maintain? The answer will probably be no.
>>
>
> alloca() is not supported in c++. In this kind of scenario you should=20
> return a copy of an object and allow the optimiser to do its job, or use =
a static=20
> thread_local buffer.
>
> Why on earth do you want to return a naked pointer to stack space?
>

Equally importantly, a naked pointer to stack space of a size/alignment *yo=
u=20
don't know* (because if you did know it, you'd just allocate it yourself=20
with `std::aligned_storage_t`, right?).

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/cd2f846a-9d68-4f6c-bb43-6872d2446efa%40isocpp.or=
g.

------=_Part_128367_2065229132.1531321810449
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, July 11, 2018 at 11:00:35 AM UTC-4, =
Richard Hodges wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, 11 Jul=
 2018 at 15:29, &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscate=
d-mailto=3D"V2nN2nxrBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;=
javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;=
;return true;">floria...@gmail.com</a>&gt; wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><br><br>Le mercredi 11 juillet 2018 16:13:0=
4 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr=
">On Wed, 11 Jul 2018 at 15:54, &lt;<a rel=3D"nofollow">floria...@gmail.com=
</a>&gt; wrote:<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"><b=
r><br>Le mercredi 11 juillet 2018 15:31:18 UTC+2, Richard Hodges a =C3=A9cr=
it=C2=A0:<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"><br><br><=
div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, 11 Jul 2018 at 15:04, &l=
t;<a rel=3D"nofollow">floria...@gmail.com</a>&gt; wrote:<br></div><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"><br><br>Le mercredi 11 juillet 2018 =
12:35:12 UTC+2, <a>gmis...@gmail.com</a> a =C3=A9crit=C2=A0:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Wednesday, July 11, 20=
18 at 8:23:51 PM UTC+12, <a>floria...@gmail.com</a> wrote:<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-left-style:solid">=
<div dir=3D"ltr"><div><br></div><div>I would like to highlight some facts: =
the <span style=3D"font-family:courier new,monospace">inline</span> keyword=
 is not about inlining. As already said by others, the abstract machine has=
 no notion of what is inlining.</div><div>The reason is simple: inlining do=
esn&#39;t change the behavior of a program, only its speed (and stack usage=
 in some cases).</div><div>The abstract machine doesn&#39;t care about spee=
d, only the bahavior.</div></div></blockquote><div><br></div><div>I&#39;m n=
ot sure keep thinking about inline on it&#39;s own is helpful to my case,=
=C2=A0though perhaps it might be for your case.</div><div>But see my commen=
t later.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:r=
gb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"=
ltr"><div><br></div><div>Currently, what <span style=3D"font-family:courier=
 new,monospace">inline</span> is about is multiple definition of a single f=
unction/object across translation units.<br></div><div>If you want extra in=
formation, have a look at <a href=3D"https://www.google.com/url?q=3Dhttps%3=
A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline&amp;sa=3DD&amp;snt=
z=3D1&amp;usg=3DAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw" rel=3D"nofollow" target=
=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3=
dhttps%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true=
;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%=
2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Finline\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNGSULKdUyQcwORlrV7uAN6nFcNoCw&#39;;return true;">https://en=
..cppreference.com/w/<wbr>cpp/language/inline</a></div><div><br></div><div>T=
hat being said, it would still be interested to have a force inline.</div><=
div>The best example I can think of is calling alloca within a function, an=
d returning the pointer. On every compilers I tested, the allocated stack m=
emory is kept after this call iif the call is actually inlined.</div><div>O=
ne use case would be runtime size class:</div><div><div style=3D"border:1px=
 solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><span=
 style=3D"color:rgb(0,0,136)">template</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"co=
lor:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><s=
pan style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)=
">class</span><span style=3D"color:rgb(0,0,0)"> stack_array </span><span st=
yle=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">private</span><span style=
=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 T</span><span style=3D"color:rgb(102,102,0)">*</span><span style=
=3D"color:rgb(0,0,0)"> p</span><span style=3D"color:rgb(102,102,0)">;</span=
><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rg=
b(0,0,136)">public</span><span style=3D"color:rgb(102,102,0)">:</span><span=
 style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:r=
gb(0,0,136)">inline</span><span style=3D"color:rgb(102,102,0)">!</span><spa=
n style=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style=3D"color:rgb(0,0,136)">int</span><span style=
=3D"color:rgb(0,0,0)"> n</span><span style=3D"color:rgb(102,102,0)">)</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,=
0)">:</span><span style=3D"color:rgb(0,0,0)"> p</span><span style=3D"color:=
rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">alloca</span><span=
 style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">n =
</span><span style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">sizeof</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">T</spa=
n><span style=3D"color:rgb(102,102,0)">)))</span><span style=3D"color:rgb(0=
,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{}</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:r=
gb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 s=
tack_array</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> stack=
_array</span><span style=3D"color:rgb(102,102,0)">&amp;)</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">delete</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D=
"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 stack_array</span><span style=3D"color=
:rgb(102,102,0)">&amp;</span><span style=3D"color:rgb(0,0,0)"> </span><span=
 style=3D"color:rgb(0,0,136)">operator</span><span style=3D"color:rgb(102,1=
02,0)">=3D(</span><span style=3D"color:rgb(0,0,136)">const</span><span styl=
e=3D"color:rgb(0,0,0)"> stack_array</span><span style=3D"color:rgb(102,102,=
0)">&amp;)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(0,0,136)">delete</span><span style=3D"color:rgb(102,10=
2,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:rgb(102,102,0)">~</span><span style=3D"color:rgb(0,0,0)">=
stack_array</span><span style=3D"color:rgb(102,102,0)">()</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">default</span><span style=3D"color:rgb(102,102,0)">;</span><span style=
=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb=
(136,0,0)">/* ... */</span><span style=3D"color:rgb(0,0,0)"><br></span><spa=
n style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)">=
<br></span></div></code></div><br>Now, to standardize that kind of stuff, I=
 think we should speak in terms of scopes:</div><div>the internal scope of =
an inline! function is the same as the scope where the call is performed.</=
div><div>As the alloca memory is &quot;deallocated&quot; at the end of the =
scope, we have the expected behavior.</div><div><br></div><div>For this to =
work, the definition of the inline! function must be visible at the call si=
te, and the simplest way to implement it in the compiler is to actually per=
form inlining.</div><div>With such a definition, inline! cannot be implemen=
ted with an attribute as it changes the semantic of the program, and cannot=
 be ignored.<br></div></div></blockquote><div><br></div><div>People compile=
 their code and when they don&#39;t get the result they want, they use __fo=
rceinline or=C2=A0always_inline or resort to that immediately.</div><div>At=
 that point they now have compiler specific code and macros. If they had in=
line! in terms=C2=A0in the mentioned they would have less of that type of c=
ode.</div><div>My description of inline! if defined in terms of __forceinli=
ne and always_inline.</div><div><br></div><div>What you are after sounds li=
ke something more complicated and therefore a=C2=A0different feature than w=
hat my suggestion is aiming for.</div><div>I&#39;ve little doubt that what =
you want is of value but you are opening more cans of worms to get it.</div=
><div>A question to ask also is does your feature likely promise to do the =
thing that=C2=A0makes people reach for=C2=A0__forceinline and always_inline=
..</div><div><br></div><div>I don&#39;t really have much of a problem with a=
nything you&#39;ve said other than I think if everyone heads off to define =
that what you are talking about I suspect it&#39;ll be something else to wh=
at I&#39;m proposing.=C2=A0If it makes C++ better, ok. It seems there are a=
 few features in this space that people need.</div></div></blockquote><div>=
<br></div><div>What I&#39;m after is a way to integrate force inlining into=
 the language using the terms of the language itself.</div><div>Inlining is=
 an optimization, and like any other optimizations, it is outside the langu=
age.</div><div>You could say mandatory RVO is an exception, but actually, t=
his optimization is expressed within the language itself, and not like an o=
ptimization (with prvalues and copy elision).</div><div><br></div><div>If y=
ou want to integrate an optimization within the language itself, it should =
makes something possible:</div><div>mandatory copy elision allows to return=
 non-copyable, non moveable objects.</div><div>In case of forced inlining, =
it would allow to allocate objects in the caller scope.</div></div></blockq=
uote><div><br></div><div>This is already available, and can be fully expres=
sed in the language as is.=C2=A0</div><div>Either by dependency injection o=
r passing a reference to=C2=A0<font face=3D"monospace, monospace">std::alig=
ned_storage</font>, depending on when you want the constructor/destructor t=
o fire.=C2=A0</div><div>Why someone would want to express in which stack fr=
ame to store the object as <i><u>semantic intent</u></i> is a mystery to me=
.. It&#39;s an implementation detail (as is the idea of a stack frame!). The=
refore it is non-portable. Therefore it has no place in the language.</div>=
</div></div></blockquote><div><br></div><div>No, in the implementation you =
propose the storage is allocated by caller, and passed to the callee. But t=
he caller might not know how much the callee wants to allocate.</div><div><=
br></div><div>Also, I never talked about stack frame, which are unknown to =
the language. I talked about scopes (which is in practice related to stack =
frames).</div><div>Scopes have 2 purposes: specifying which names are visib=
les, and specifying when objects are destructed.</div><div>What I propose i=
s to change the second point for inline! functions. This would be a semanti=
c change, not just an implementation change.</div><div><br></div><div>The i=
ntent would be: the locals of an inline! function outlive the function call=
, and will be destroyed at the same time as the caller locals, ie: callee a=
nd caller locals are in the same scope.</div><div>I&#39;m pretty sure you c=
ould use it to avoid some dangling references.<br></div></div></blockquote>=
<div><br></div><div>This is already expressible:</div><div><br></div><div><=
div style=3D"color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><font=
 face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,255)">#include<=
/span><span style=3D"color:rgb(0,0,0)"> &lt;tuple&gt;</span></font></div><d=
iv><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,255)">#=
include</span><span style=3D"color:rgb(0,0,0)"> &lt;string&gt;</span></font=
></div><font face=3D"monospace, monospace"><br></font><div><font face=3D"mo=
nospace, monospace"><span style=3D"color:rgb(0,0,0)">std::tuple&lt;</span><=
span style=3D"color:rgb(0,0,255)">int</span><span style=3D"color:rgb(0,0,0)=
">, std::string&gt; foo();</span></font></div><font face=3D"monospace, mono=
space"><br></font><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monos=
pace, monospace">std::size_t bar()</font></span></div><div><span style=3D"c=
olor:rgb(0,0,0)"><font face=3D"monospace, monospace">{</font></span></div><=
div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></=
span><span style=3D"color:rgb(0,0,255)">=C2=A0 auto</span><span style=3D"co=
lor:rgb(0,0,0)">&amp;&amp; [ a, b ]  =3D foo();</span></font></div><div><fo=
nt face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></span><s=
pan style=3D"color:rgb(0,0,255)">=C2=A0 return</span><span style=3D"color:r=
gb(0,0,0)"> a + b.size();=C2=A0 // a and b outlive scope of foo()</span></f=
ont></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, mo=
nospace">}</font></span></div><br></div><br></div></div></div></blockquote>=
<div>=C2=A0True, that works, but it is the exact same problem as above: the=
 caller need to know the temporaries needed by the actual/useful return val=
ue from the callee.</div><div>This is not about extending the lifetime of t=
he return values, but extend the lifetime of all locals, without the caller=
 being aware.<br></div><div>Also, that doesn&#39;t work with alloca(). I&#3=
9;m not sure what C++ says about alloca, though.</div><div><br></div><div><=
div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187=
);border-style:solid;border-width:1px"><code><div><span style=3D"color:#800=
">// create a safe buffer for C string manipulation with runtime size</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">inline</s=
pan><span style=3D"color:#660">!</span><span style=3D"color:#000"> </span><=
span style=3D"color:#008">char</span><span style=3D"color:#660">*</span><sp=
an style=3D"color:#000"> buffer</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#008">int</span><span style=3D"color:#000"> n</span><spa=
n style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><spa=
n style=3D"color:#008">char</span><span style=3D"color:#660">*</span><span =
style=3D"color:#000"> p </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> alloca</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">n</span><span style=3D"color:#660">+</span><span style=
=3D"color:#066">1</span><span style=3D"color:#660">);</span><span style=3D"=
color:#000"> </span><span style=3D"color:#800">// +1 to be safe cannot be f=
orgotten</span><span style=3D"color:#000"><br>=C2=A0 memset</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">p</span><span style=3D=
"color:#660">,</span><span style=3D"color:#000"> n</span><span style=3D"col=
or:#660">+</span><span style=3D"color:#066">1</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0=
</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=
=C2=A0 </span><span style=3D"color:#008">return</span><span style=3D"color:=
#000"> p</span><span style=3D"color:#660">;</span><span style=3D"color:#000=
"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000">=
<br><br></span><span style=3D"color:#008">void</span><span style=3D"color:#=
000"> foo</span><span style=3D"color:#660">(</span><span style=3D"color:#00=
8">const</span><span style=3D"color:#000"> </span><span style=3D"color:#008=
">char</span><span style=3D"color:#660">*</span><span style=3D"color:#000">=
 s</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 </span><span style=3D"color:#008">char</span><span style=3D"color:#660"=
>*</span><span style=3D"color:#000"> buf </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> buffer</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">strlen</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">s</span><span style=3D"color:#660">))=
;</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#=
800">/* do something with buf */</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></s=
pan></div></code></div>Here, the actual buffer returned by alloca cannot cu=
rrently outlive the call to buffer, and there is no easy way to do it.</div=
><div>How would you do that? Is your implementation easy to read/write/main=
tain? The answer will probably be no.</div></div></blockquote><div><br></di=
v><div>alloca() is not supported in c++. In this kind of scenario you shoul=
d return a copy of an object and allow the optimiser to do its job, or use =
a <font face=3D"monospace, monospace">static thread_local </font>buffer.</d=
iv><div><br></div><div>Why on earth do you want to return a naked pointer t=
o stack space?</div></div></div></blockquote><div><br></div><div>Equally im=
portantly, a naked pointer to stack space of a size/alignment <i>you don&#3=
9;t know</i> (because if you did know it, you&#39;d just allocate it yourse=
lf with `std::aligned_storage_t`, right?).</div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cd2f846a-9d68-4f6c-bb43-6872d2446efa%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cd2f846a-9d68-4f6c-bb43-6872d2446efa=
%40isocpp.org</a>.<br />

------=_Part_128367_2065229132.1531321810449--

------=_Part_128366_1671436022.1531321810448--

.


Author: florian.csdt@gmail.com
Date: Wed, 11 Jul 2018 08:26:44 -0700 (PDT)
Raw View
------=_Part_22424_626872265.1531322804476
Content-Type: multipart/alternative;
 boundary="----=_Part_22425_1682729575.1531322804476"

------=_Part_22425_1682729575.1531322804476
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



> alloca() is not supported in c++. In this kind of scenario you should=20
> return a copy of an object and allow the optimiser to do its job, or use =
a static=20
> thread_local buffer.
>
> Why on earth do you want to return a naked pointer to stack space?
>

@Richard:
First, it was a short, simple and comprehensive example, but you can=20
imagine returning more complex objects. Actually, my very first example was=
=20
a simulating a runtime sized object.
Then, you seem to forget that a lot of code need to be interfaced with C;=
=20
hence the use of raw pointers.

Then, the compiler cannot fully optimize (currently) returning tuples at=20
the calle site (caller is fine though): https://godbolt.org/g/Vk6PKx.

Le mercredi 11 juillet 2018 17:06:38 UTC+2, Nicol Bolas a =C3=A9crit :

> But what you're talking about isn't really a function anymore. If the=20
> object still exists but has no name... what exactly is the point of it?=
=20
> Unless the function stored a pointer/reference to these objects somewhere=
=20
> that the outer scope can access it, why do those objects need to exist?
>
> And if it could do that, why not just let the names be accessible too? If=
=20
> we're relying on the existence of some objects, then rely on it already.=
=20
> And if we're going that far, why not allow the `inline!` function be able=
=20
> to return *for* its caller rather than *to* its caller? Or affect its=20
> caller in other ways.
>
> You can see that we're quickly moving away from being a mere "function"=
=20
> and becoming something else: a named series of statements that get=20
> copy-pasted into code. That might be a useful feature or a confusing one.=
=20
> But this half-state between them that you propose is exactly that: a=20
> half-state. Neither one thing nor the other, the construct is only useful=
=20
> in a trivial number of instances.
>

 @Nicol:
Here, you're completely right: those are not really functions anymore.

However, I would avoid putting names in the caller scope: this more=20
annoying than it is solving issues.
Keeping temporaries because they are referenced elsewhere would be the main=
=20
goal.
When you use macros, how often do you need to leak a name vs you need to=20
create a unique name for your locals?

I keep thinking it is much less confusing than macros. And the first idea=
=20
was to allow force inlining, and how to specify it into the language.

Equally importantly, a naked pointer to stack space of a size/alignment *yo=
u=20
> don't know* (because if you did know it, you'd just allocate it yourself=
=20
> with `std::aligned_storage_t`, right?).
>

Alignment is a non issue because it is easy to overallocate and return the=
=20
first address with the propoer alignment. Moreover, the stack should always=
=20
be aligned with (at least) alignof(std::max_align_t ). On x86, the default=
=20
alignment is even 16.
Also, if C++ had VLAs, you could create a VLA instead of alloca, and the=20
alignment would be handled by the compiler (btw, all c++ compilers are able=
=20
to handle VLAs).

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1d91ded8-04f8-4306-9ee3-5ca808b91719%40isocpp.or=
g.

------=_Part_22425_1682729575.1531322804476
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-l=
eft: 1ex;"><div>alloca()
 is not supported in c++. In this kind of scenario you should return a=20
copy of an object and allow the optimiser to do its job, or use a <font fac=
e=3D"monospace, monospace">static thread_local </font>buffer.</div><div><br=
></div><div>Why on earth do you want to return a naked pointer to stack spa=
ce?</div></blockquote><br><div>@Richard:<br></div><div>First,
 it was a short, simple and comprehensive example, but you can imagine=20
returning more complex objects. Actually, my very first example was a=20
simulating a runtime sized object.</div><div>Then, you seem to forget that =
a lot of code need to be interfaced with C; hence the use of raw pointers.<=
/div><div><br></div>Then, the compiler cannot fully optimize (currently) re=
turning tuples at the calle site (caller is fine though): https://godbolt.o=
rg/g/Vk6PKx.<br><br>Le mercredi 11 juillet 2018 17:06:38 UTC+2, Nicol Bolas=
 a =C3=A9crit=C2=A0:<br><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div>But what you&#39;re talking about isn&#39;t really a functi=
on anymore. If the object still exists but has no name... what exactly is t=
he point of it? Unless the function stored a pointer/reference to these obj=
ects somewhere that the outer scope can access it, why do those objects nee=
d to exist?<br></div><div><br></div><div>And if it could do that, why not j=
ust let the names be accessible too? If we&#39;re relying on the existence =
of some objects, then rely on it already. And if we&#39;re going that far, =
why not allow the `inline!` function be able to return <i>for</i> its calle=
r rather than <i>to</i> its caller? Or affect its caller in other ways.</di=
v><div><br></div><div>You can see that we&#39;re quickly moving away from b=
eing a mere &quot;function&quot; and becoming something else: a named serie=
s of statements that get copy-pasted into code. That might be a useful feat=
ure or a confusing one. But this half-state between them that you propose i=
s exactly that: a half-state. Neither one thing nor the other, the construc=
t is only useful in a trivial number of instances.<br></div></div></blockqu=
ote><div><br></div><div>=C2=A0@Nicol:</div><div>Here, you&#39;re completely=
 right: those are not really functions anymore.</div><div><br></div><div>Ho=
wever, I would avoid putting names in the caller scope: this more annoying =
than it is solving issues.<div>Keeping temporaries because they are referen=
ced elsewhere would be the main goal.</div></div><div>When you use macros, =
how often do you need to leak a name vs you need to create a unique name fo=
r your locals?</div><div><br></div><div>I keep thinking it is much less con=
fusing than macros. And the first idea was to allow force inlining, and how=
 to specify it into the language.</div><div><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb=
(204, 204, 204); padding-left: 1ex;"><div>Equally importantly, a naked poin=
ter to stack space of a size/alignment <i>you don&#39;t know</i> (because i=
f you did know it, you&#39;d just allocate it yourself with `std::aligned_s=
torage_t`, right?).</div></blockquote><div><br></div><div>Alignment is a no=
n issue because it is easy to overallocate and return the first address wit=
h the propoer alignment. Moreover, the stack should always be aligned with =
(at least) alignof(std::max_align_t ). On x86, the default alignment is eve=
n 16.</div><div>Also, if C++ had VLAs, you could create a VLA instead of al=
loca, and the alignment would be handled by the compiler (btw, all c++ comp=
ilers are able to handle VLAs).<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1d91ded8-04f8-4306-9ee3-5ca808b91719%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1d91ded8-04f8-4306-9ee3-5ca808b91719=
%40isocpp.org</a>.<br />

------=_Part_22425_1682729575.1531322804476--

------=_Part_22424_626872265.1531322804476--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Wed, 11 Jul 2018 16:48:30 +0100
Raw View
--00000000000054b6530570bb2ebe
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 11 Jul 2018 at 16:26, <florian.csdt@gmail.com> wrote:

> alloca() is not supported in c++. In this kind of scenario you should
>> return a copy of an object and allow the optimiser to do its job, or use=
 a static
>> thread_local buffer.
>>
>> Why on earth do you want to return a naked pointer to stack space?
>>
>
> @Richard:
> First, it was a short, simple and comprehensive example, but you can
> imagine returning more complex objects. Actually, my very first example w=
as
> a simulating a runtime sized object.
> Then, you seem to forget that a lot of code need to be interfaced with C;
> hence the use of raw pointers.
>
> Then, the compiler cannot fully optimize (currently) returning tuples at
> the calle site (caller is fine though): https://godbolt.org/g/Vk6PKx.
>

At which point I suggest filing a 'missed-optimisation' bug report to the
compiler writers.

The correct response to finding sub-optimal behaviour in a compiler is to
fix the compiler, not to introduce an esoteric language feature. C++ is
already hard to teach because of historical bizarreness. Let's not make it
worse!

:)



> Le mercredi 11 juillet 2018 17:06:38 UTC+2, Nicol Bolas a =C3=A9crit :
>
>> But what you're talking about isn't really a function anymore. If the
>> object still exists but has no name... what exactly is the point of it?
>> Unless the function stored a pointer/reference to these objects somewher=
e
>> that the outer scope can access it, why do those objects need to exist?
>>
>> And if it could do that, why not just let the names be accessible too? I=
f
>> we're relying on the existence of some objects, then rely on it already.
>> And if we're going that far, why not allow the `inline!` function be abl=
e
>> to return *for* its caller rather than *to* its caller? Or affect its
>> caller in other ways.
>>
>> You can see that we're quickly moving away from being a mere "function"
>> and becoming something else: a named series of statements that get
>> copy-pasted into code. That might be a useful feature or a confusing one=
..
>> But this half-state between them that you propose is exactly that: a
>> half-state. Neither one thing nor the other, the construct is only usefu=
l
>> in a trivial number of instances.
>>
>
>  @Nicol:
> Here, you're completely right: those are not really functions anymore.
>
> However, I would avoid putting names in the caller scope: this more
> annoying than it is solving issues.
> Keeping temporaries because they are referenced elsewhere would be the
> main goal.
> When you use macros, how often do you need to leak a name vs you need to
> create a unique name for your locals?
>
> I keep thinking it is much less confusing than macros. And the first idea
> was to allow force inlining, and how to specify it into the language.
>
> Equally importantly, a naked pointer to stack space of a size/alignment *=
you
>> don't know* (because if you did know it, you'd just allocate it yourself
>> with `std::aligned_storage_t`, right?).
>>
>
> Alignment is a non issue because it is easy to overallocate and return th=
e
> first address with the propoer alignment. Moreover, the stack should alwa=
ys
> be aligned with (at least) alignof(std::max_align_t ). On x86, the defaul=
t
> alignment is even 16.
> Also, if C++ had VLAs, you could create a VLA instead of alloca, and the
> alignment would be handled by the compiler (btw, all c++ compilers are ab=
le
> to handle VLAs).
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1d91ded8-04f=
8-4306-9ee3-5ca808b91719%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1d91ded8-04=
f8-4306-9ee3-5ca808b91719%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hbaUX74bEUAFu7JbnP1CG9R-8HCbVvNwTbpFRjbPNr=
dog%40mail.gmail.com.

--00000000000054b6530570bb2ebe
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, 11 Jul 2018 at 16:26, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><div>alloca()
 is not supported in c++. In this kind of scenario you should return a=20
copy of an object and allow the optimiser to do its job, or use a <font fac=
e=3D"monospace, monospace">static thread_local </font>buffer.</div><div><br=
></div><div>Why on earth do you want to return a naked pointer to stack spa=
ce?</div></blockquote><br><div>@Richard:<br></div><div>First,
 it was a short, simple and comprehensive example, but you can imagine=20
returning more complex objects. Actually, my very first example was a=20
simulating a runtime sized object.</div><div>Then, you seem to forget that =
a lot of code need to be interfaced with C; hence the use of raw pointers.<=
/div><div><br></div>Then, the compiler cannot fully optimize (currently) re=
turning tuples at the calle site (caller is fine though): <a href=3D"https:=
//godbolt.org/g/Vk6PKx" target=3D"_blank">https://godbolt.org/g/Vk6PKx</a>.=
<br></div></blockquote><div><br></div><div>At which point I suggest filing =
a &#39;missed-optimisation&#39; bug report to the compiler writers.=C2=A0</=
div><div><br></div><div>The correct response to finding sub-optimal behavio=
ur in a compiler is to fix the compiler, not to introduce an esoteric langu=
age feature. C++ is already hard to teach because of historical bizarreness=
.. Let&#39;s not make it worse!=C2=A0</div><div><br></div><div>:)</div><div>=
<br></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"><b=
r>Le mercredi 11 juillet 2018 17:06:38 UTC+2, Nicol Bolas a =C3=A9crit=C2=
=A0:<br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But w=
hat you&#39;re talking about isn&#39;t really a function anymore. If the ob=
ject still exists but has no name... what exactly is the point of it? Unles=
s the function stored a pointer/reference to these objects somewhere that t=
he outer scope can access it, why do those objects need to exist?<br></div>=
<div><br></div><div>And if it could do that, why not just let the names be =
accessible too? If we&#39;re relying on the existence of some objects, then=
 rely on it already. And if we&#39;re going that far, why not allow the `in=
line!` function be able to return <i>for</i> its caller rather than <i>to</=
i> its caller? Or affect its caller in other ways.</div><div><br></div><div=
>You can see that we&#39;re quickly moving away from being a mere &quot;fun=
ction&quot; and becoming something else: a named series of statements that =
get copy-pasted into code. That might be a useful feature or a confusing on=
e. But this half-state between them that you propose is exactly that: a hal=
f-state. Neither one thing nor the other, the construct is only useful in a=
 trivial number of instances.<br></div></div></blockquote><div><br></div><d=
iv>=C2=A0@Nicol:</div><div>Here, you&#39;re completely right: those are not=
 really functions anymore.</div><div><br></div><div>However, I would avoid =
putting names in the caller scope: this more annoying than it is solving is=
sues.<div>Keeping temporaries because they are referenced elsewhere would b=
e the main goal.</div></div><div>When you use macros, how often do you need=
 to leak a name vs you need to create a unique name for your locals?</div><=
div><br></div><div>I keep thinking it is much less confusing than macros. A=
nd the first idea was to allow force inlining, and how to specify it into t=
he language.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-le=
ft:1ex"><div>Equally importantly, a naked pointer to stack space of a size/=
alignment <i>you don&#39;t know</i> (because if you did know it, you&#39;d =
just allocate it yourself with `std::aligned_storage_t`, right?).</div></bl=
ockquote><div><br></div><div>Alignment is a non issue because it is easy to=
 overallocate and return the first address with the propoer alignment. More=
over, the stack should always be aligned with (at least) alignof(std::max_a=
lign_t ). On x86, the default alignment is even 16.</div><div>Also, if C++ =
had VLAs, you could create a VLA instead of alloca, and the alignment would=
 be handled by the compiler (btw, all c++ compilers are able to handle VLAs=
).<br></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1d91ded8-04f8-4306-9ee3-5ca808b91719%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1d91ded8-04f8-=
4306-9ee3-5ca808b91719%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hbaUX74bEUAFu7JbnP1CG9R-8HCbVvN=
wTbpFRjbPNrdog%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbaUX74bEUA=
Fu7JbnP1CG9R-8HCbVvNwTbpFRjbPNrdog%40mail.gmail.com</a>.<br />

--00000000000054b6530570bb2ebe--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Thu, 12 Jul 2018 03:34:08 +0200
Raw View
On Wed, Jul 11, 2018 at 08:26:44AM -0700, florian.csdt@gmail.com wrote:
>
>
> >
> > And if it could do that, why not just let the names be accessible too? If
> > we're relying on the existence of some objects, then rely on it already.
> > And if we're going that far, why not allow the `inline!` function be able
> > to return *for* its caller rather than *to* its caller? Or affect its
> > caller in other ways.
> >
> > You can see that we're quickly moving away from being a mere "function"
> > and becoming something else: a named series of statements that get
> > copy-pasted into code. That might be a useful feature or a confusing one.
> > But this half-state between them that you propose is exactly that: a
> > half-state. Neither one thing nor the other, the construct is only useful
> > in a trivial number of instances.
> >
>
>  @Nicol:
> Here, you're completely right: those are not really functions anymore.
>
> However, I would avoid putting names in the caller scope: this more
> annoying than it is solving issues.
> Keeping temporaries because they are referenced elsewhere would be the main
> goal.

I would say it was a novel but peculiar way to introduce anonymous variables.

inline! std::string_view makeFoo()
{
  std::string mAnon(initialize());
  return mAnon;
}

Thanks to the inline! the string_view is valid in the returned context.

template <class T>
inline! void anonymize(T&& t) { T aT(std::forward<T>(t)); }

Use this one like

  anonymize(stack_guard([](){...}));

Useful feature but somewhat surprising syntax.

/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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180712013408.GA14754%40noemi.bahnhof.se.

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Thu, 12 Jul 2018 09:05:37 +0200
Raw View
--0000000000003600a00570c7fe80
Content-Type: text/plain; charset="UTF-8"

On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <magfr@lysator.liu.se> wrote:

> On Wed, Jul 11, 2018 at 08:26:44AM -0700, florian.csdt@gmail.com wrote:
> >
> >
> > >
> > > And if it could do that, why not just let the names be accessible too?
> If
> > > we're relying on the existence of some objects, then rely on it
> already.
> > > And if we're going that far, why not allow the `inline!` function be
> able
> > > to return *for* its caller rather than *to* its caller? Or affect its
> > > caller in other ways.
> > >
> > > You can see that we're quickly moving away from being a mere
> "function"
> > > and becoming something else: a named series of statements that get
> > > copy-pasted into code. That might be a useful feature or a confusing
> one.
> > > But this half-state between them that you propose is exactly that: a
> > > half-state. Neither one thing nor the other, the construct is only
> useful
> > > in a trivial number of instances.
> > >
> >
> >  @Nicol:
> > Here, you're completely right: those are not really functions anymore.
> >
> > However, I would avoid putting names in the caller scope: this more
> > annoying than it is solving issues.
> > Keeping temporaries because they are referenced elsewhere would be the
> main
> > goal.
>
> I would say it was a novel but peculiar way to introduce anonymous
> variables.
>
> inline! std::string_view makeFoo()
> {
>   std::string mAnon(initialize());
>   return mAnon;
> }
>
> Thanks to the inline! the string_view is valid in the returned context.


This is adding a cryptic language feature in order to carry a dependency
through a reference in a hidden way. It is the exact opposite of all the
good things that have happened to c++ since 2011. Value semantics, good.
Tidying up after dangling references, bad.

Questions:

a) how would you express this bizzareness in the standard?

b) how would you teach it?

c) why do you want to return a string_view here (a.k.a. dangling references
mk 2) when you could simply return the string?

I'm still waiting for someone to post a real motivating use case. So far
none have been forthcoming. Frankly this is unsurprising. Some feature
ideas are simply not destined to survive birth.


>
> template <class T>
> inline! void anonymize(T&& t) { T aT(std::forward<T>(t)); }
>
> Use this one like
>
>   anonymize(stack_guard([](){...}));
>
> Useful feature but somewhat surprising syntax.
>
> /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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180712013408.GA14754%40noemi.bahnhof.se
> .
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbvmG361yaDu0p2QPOMBM8N8CuHD93qbCDs8ZXj9i9K%2Bw%40mail.gmail.com.

--0000000000003600a00570c7fe80
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu=
, 12 Jul 2018 at 03:34, Magnus Fromreide &lt;<a href=3D"mailto:magfr@lysato=
r.liu.se">magfr@lysator.liu.se</a>&gt; wrote:<br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex">On Wed, Jul 11, 2018 at 08:26:44AM -0700, <a href=3D"mailto:flor=
ian.csdt@gmail.com" target=3D"_blank">florian.csdt@gmail.com</a> wrote:<br>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div><div><br></div><div>b) how =
would you teach it?</div><div><br></div><div>c) why do you want to return a=
 string_view here (a.k.a. dangling references mk 2) when you could simply r=
eturn the string?</div><div><br></div><div>I&#39;m still waiting for someon=
e to post a real motivating use case. So far none have been forthcoming. Fr=
ankly this is unsurprising. Some feature ideas are simply not destined to s=
urvive birth.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
template &lt;class T&gt;<br>
inline! void anonymize(T&amp;&amp; t) { T aT(std::forward&lt;T&gt;(t)); }<b=
r>
<br>
Use this one like<br>
<br>
=C2=A0 anonymize(stack_guard([](){...}));<br>
<br>
Useful feature but somewhat surprising syntax.<br>
<br>
/MF<br>
<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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20180712013408.GA14754%40noemi.bahnho=
f.se" rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/20180712013408.GA14754%40noemi.bahnhof.se</a>.=
<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hbvmG361yaDu0p2QPOMBM8N8CuHD93q=
bCDs8ZXj9i9K%2Bw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbvmG361y=
aDu0p2QPOMBM8N8CuHD93qbCDs8ZXj9i9K%2Bw%40mail.gmail.com</a>.<br />

--0000000000003600a00570c7fe80--

.


Author: florian.csdt@gmail.com
Date: Thu, 12 Jul 2018 00:55:33 -0700 (PDT)
Raw View
------=_Part_109414_561336151.1531382133189
Content-Type: multipart/alternative;
 boundary="----=_Part_109415_1149741653.1531382133190"

------=_Part_109415_1149741653.1531382133190
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit :
>
>
>
> On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <ma...@lysator.liu.se=20
> <javascript:>> wrote:
>
>> On Wed, Jul 11, 2018 at 08:26:44AM -0700, floria...@gmail.com=20
>> <javascript:> wrote:
>> >=20
>> >=20
>> > >
>> > > And if it could do that, why not just let the names be accessible=20
>> too? If=20
>> > > we're relying on the existence of some objects, then rely on it=20
>> already.=20
>> > > And if we're going that far, why not allow the `inline!` function be=
=20
>> able=20
>> > > to return *for* its caller rather than *to* its caller? Or affect it=
s=20
>> > > caller in other ways.
>> > >
>> > > You can see that we're quickly moving away from being a mere=20
>> "function"=20
>> > > and becoming something else: a named series of statements that get=
=20
>> > > copy-pasted into code. That might be a useful feature or a confusing=
=20
>> one.=20
>> > > But this half-state between them that you propose is exactly that: a=
=20
>> > > half-state. Neither one thing nor the other, the construct is only=
=20
>> useful=20
>> > > in a trivial number of instances.
>> > >
>> >=20
>> >  @Nicol:
>> > Here, you're completely right: those are not really functions anymore.
>> >=20
>> > However, I would avoid putting names in the caller scope: this more=20
>> > annoying than it is solving issues.
>> > Keeping temporaries because they are referenced elsewhere would be the=
=20
>> main=20
>> > goal.
>>
>> I would say it was a novel but peculiar way to introduce anonymous=20
>> variables.
>>
>> inline! std::string_view makeFoo()
>> {
>>   std::string mAnon(initialize());
>>   return mAnon;
>> }
>>
>> Thanks to the inline! the string_view is valid in the returned context.=
=20
>
>
> This is adding a cryptic language feature in order to carry a dependency=
=20
> through a reference in a hidden way. It is the exact opposite of all the=
=20
> good things that have happened to c++ since 2011. Value semantics, good.=
=20
> Tidying up after dangling references, bad.
>
> Questions:
>
> a) how would you express this bizzareness in the standard?
>

Simple, I already did.
The callee scope is the same as the caller scope. perdiod.
All the bizareness are handled by this simple rule.
We could enforce more: like the definition must be visible, inline!=20
recursion is not allowed, taking a pointer to such a functions is not=20
allowed...


> b) how would you teach it?
>

How do you teach macros?
=20

>
> c) why do you want to return a string_view here (a.k.a. dangling=20
> references mk 2) when you could simply return the string?
>

If you need to chain functions, it can become clearer returning directly=20
the non-owning wrapper, especially if the conversion between the actual=20
object and the non owning wrapper is not automatic (std::md_span?).
But I have to say, it's a small motivation.
=20

>
> I'm still waiting for someone to post a real motivating use case. So far=
=20
> none have been forthcoming. Frankly this is unsurprising. Some feature=20
> ideas are simply not destined to survive birth.
> =20
>

I already post a valid use case I needed quite a lot: "returning" runtime=
=20
sized objects.
Even if you had VLAs, it would still not be possible to return them, only a=
=20
view on it. So the only way to have this working is the allocated space=20
must outlive the callee.
And alloca might not be part of the C++ standard, it is part of POSIX,=20
hence is supported by most platforms (it is also supported on windows).
So it is possible (and easy) to write portable code using alloca. But as=20
you cannot really return the allocated space from alloca, you need to=20
either do heap allocations (slow), or rely on macros (bad).
And this inline! would be a big step forward to use such mechanism.

You could argue it would be better to standardize runtime sized objects,=20
and I would agree. But the cost of standardizing such objects is extremely=
=20
high, especially if you allow to return such objects.
My proposal is the opposite: it is simple to standardize/implement, while=
=20
still being useful.

You did not even try to say why it is bad. You just said it is somehow=20
possible now (except the part with alloca, which is my main use case for=20
that), but it requires more lines, is more cryptic to read...

I don't say what I propose should defenitely go into the standard. It is=20
not perfect and I know it. But I answered clearly to all your objections,=
=20
and you don't really have valid arguments against it.
So please take time to consider everything I said before writing a reply,=
=20
otherwise your might repeat objections I already answered without any added=
=20
value.

Also, don't forget the start point: a way to have forced inlining in the=20
laguage using the terms of the language itself.
You might disagree that it is useful to standardize forced inlining, and=20
you might be right in theory.
In practice, this feature is used in so many codebases that it might be=20
worth standardizing.
And what I propose is a simple way to do it. I think it is even simpler=20
like that than an attribute (because we cannot talk properly about inlining=
=20
within the standard).

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/e2200f64-c7f2-4360-aed9-2e0acbaaea77%40isocpp.or=
g.

------=_Part_109415_1149741653.1531382133190
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard H=
odges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 =
Jul 2018 at 03:34, Magnus Fromreide &lt;<a href=3D"javascript:" target=3D"_=
blank" gdf-obfuscated-mailto=3D"AjmwacnwCAAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D=
&#39;javascript:&#39;;return true;">ma...@lysator.liu.se</a>&gt; wrote:<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">On Wed, Jul 11, 2018 at 08:26:44AM -07=
00, <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"Ajmw=
acnwCAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;=
;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">f=
loria...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div></div></div></blockquote><d=
iv><br></div><div>Simple, I already did.</div><div>The callee scope is the =
same as the caller scope. perdiod.</div><div>All the bizareness are handled=
 by this simple rule.</div><div>We could enforce more: like the definition =
must be visible, inline! recursion is not allowed, taking a pointer to such=
 a functions is not allowed...<br></div><div> <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><di=
v><br></div><div>b) how would you teach it?</div></div></div></blockquote><=
div><br></div><div>How do you teach macros?<br></div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmai=
l_quote"><div><br></div><div>c) why do you want to return a string_view her=
e (a.k.a. dangling references mk 2) when you could simply return the string=
?</div></div></div></blockquote><div><br></div><div>If you need to chain fu=
nctions, it can become clearer returning directly the non-owning wrapper, e=
specially if the conversion between the actual object and the non owning wr=
apper is not automatic (std::md_span?).</div><div>But I have to say, it&#39=
;s a small motivation.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></d=
iv><div>I&#39;m still waiting for someone to post a real motivating use cas=
e. So far none have been forthcoming. Frankly this is unsurprising. Some fe=
ature ideas are simply not destined to survive birth.</div><div>=C2=A0</div=
></div></div></blockquote><div><br></div><div>I already post a valid use ca=
se I needed quite a lot: &quot;returning&quot; runtime sized objects.</div>=
<div>Even if you had VLAs, it would still not be possible to return them, o=
nly a view on it. So the only way to have this working is the allocated spa=
ce must outlive the callee.</div><div>And alloca might not be part of the C=
++ standard, it is part of POSIX, hence is supported by most platforms (it =
is also supported on windows).</div><div>So it is possible (and easy) to wr=
ite portable code using alloca. But as you cannot really return the allocat=
ed space from alloca, you need to either do heap allocations (slow), or rel=
y on macros (bad).</div><div>And this inline! would be a big step forward t=
o use such mechanism.</div><div><br></div><div>You could argue it would be =
better to standardize runtime sized objects, and I would agree. But the cos=
t of standardizing such objects is extremely high, especially if you allow =
to return such objects.</div><div>My proposal is the opposite: it is simple=
 to standardize/implement, while still being useful.<br></div><div><br></di=
v><div>You did not even try to say why it is bad. You just said it is someh=
ow possible now (except the part with alloca, which is my main use case for=
 that), but it requires more lines, is more cryptic to read...</div><div><b=
r></div><div>I don&#39;t say what I propose should defenitely go into the s=
tandard. It is not perfect and I know it. But I answered clearly to all you=
r objections, and you don&#39;t really have valid arguments against it.</di=
v><div>So please take time to consider everything I said before writing a r=
eply, otherwise your might repeat objections I already answered without any=
 added value.</div><div><br></div><div>Also, don&#39;t forget the start poi=
nt: a way to have forced inlining in the laguage using the terms of the lan=
guage itself.</div><div>You might disagree that it is useful to standardize=
 forced inlining, and you might be right in theory.</div><div>In practice, =
this feature is used in so many codebases that it might be worth standardiz=
ing.</div><div>And what I propose is a simple way to do it. I think it is e=
ven simpler like that than an attribute (because we cannot talk properly ab=
out inlining within the standard).<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e2200f64-c7f2-4360-aed9-2e0acbaaea77%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e2200f64-c7f2-4360-aed9-2e0acbaaea77=
%40isocpp.org</a>.<br />

------=_Part_109415_1149741653.1531382133190--

------=_Part_109414_561336151.1531382133189--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Thu, 12 Jul 2018 10:36:24 +0200
Raw View
--000000000000e1ed700570c94238
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Thu, 12 Jul 2018 at 09:55, <florian.csdt@gmail.com> wrote:

>
>
> Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit :
>>
>>
>>
>> On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <ma...@lysator.liu.se>
>> wrote:
>>
>>> On Wed, Jul 11, 2018 at 08:26:44AM -0700, floria...@gmail.com wrote:
>>> >
>>> >
>>> > >
>>> > > And if it could do that, why not just let the names be accessible
>>> too? If
>>> > > we're relying on the existence of some objects, then rely on it
>>> already.
>>> > > And if we're going that far, why not allow the `inline!` function b=
e
>>> able
>>> > > to return *for* its caller rather than *to* its caller? Or affect
>>> its
>>> > > caller in other ways.
>>> > >
>>> > > You can see that we're quickly moving away from being a mere
>>> "function"
>>> > > and becoming something else: a named series of statements that get
>>> > > copy-pasted into code. That might be a useful feature or a confusin=
g
>>> one.
>>> > > But this half-state between them that you propose is exactly that: =
a
>>> > > half-state. Neither one thing nor the other, the construct is only
>>> useful
>>> > > in a trivial number of instances.
>>> > >
>>> >
>>> >  @Nicol:
>>> > Here, you're completely right: those are not really functions anymore=
..
>>> >
>>> > However, I would avoid putting names in the caller scope: this more
>>> > annoying than it is solving issues.
>>> > Keeping temporaries because they are referenced elsewhere would be th=
e
>>> main
>>> > goal.
>>>
>>> I would say it was a novel but peculiar way to introduce anonymous
>>> variables.
>>>
>>> inline! std::string_view makeFoo()
>>> {
>>>   std::string mAnon(initialize());
>>>   return mAnon;
>>> }
>>>
>>> Thanks to the inline! the string_view is valid in the returned context.
>>
>>
>> This is adding a cryptic language feature in order to carry a dependency
>> through a reference in a hidden way. It is the exact opposite of all the
>> good things that have happened to c++ since 2011. Value semantics, good.
>> Tidying up after dangling references, bad.
>>
>> Questions:
>>
>> a) how would you express this bizzareness in the standard?
>>
>
> Simple, I already did.
> The callee scope is the same as the caller scope. perdiod.
> All the bizareness are handled by this simple rule.
> We could enforce more: like the definition must be visible, inline!
> recursion is not allowed, taking a pointer to such a functions is not
> allowed...
>
>
>> b) how would you teach it?
>>
>
> How do you teach macros?
>
>
>>
>> c) why do you want to return a string_view here (a.k.a. dangling
>> references mk 2) when you could simply return the string?
>>
>
> If you need to chain functions, it can become clearer returning directly
> the non-owning wrapper, especially if the conversion between the actual
> object and the non owning wrapper is not automatic (std::md_span?).
> But I have to say, it's a small motivation.
>
>
>>
>> I'm still waiting for someone to post a real motivating use case. So far
>> none have been forthcoming. Frankly this is unsurprising. Some feature
>> ideas are simply not destined to survive birth.
>>
>>
>
> I already post a valid use case I needed quite a lot: "returning" runtime
> sized objects.
> Even if you had VLAs, it would still not be possible to return them, only
> a view on it. So the only way to have this working is the allocated space
> must outlive the callee.
> And alloca might not be part of the C++ standard, it is part of POSIX,
> hence is supported by most platforms (it is also supported on windows).
> So it is possible (and easy) to write portable code using alloca. But as
> you cannot really return the allocated space from alloca, you need to
> either do heap allocations (slow), or rely on macros (bad).
> And this inline! would be a big step forward to use such mechanism.
>
> You could argue it would be better to standardize runtime sized objects,
> and I would agree. But the cost of standardizing such objects is extremel=
y
> high, especially if you allow to return such objects.
> My proposal is the opposite: it is simple to standardize/implement, while
> still being useful.
>
> You did not even try to say why it is bad. You just said it is somehow
> possible now (except the part with alloca, which is my main use case for
> that), but it requires more lines, is more cryptic to read...
>
> I don't say what I propose should defenitely go into the standard. It is
> not perfect and I know it. But I answered clearly to all your objections,
> and you don't really have valid arguments against it.
> So please take time to consider everything I said before writing a reply,
> otherwise your might repeat objections I already answered without any add=
ed
> value.
>
> Also, don't forget the start point: a way to have forced inlining in the
> laguage using the terms of the language itself.
> You might disagree that it is useful to standardize forced inlining, and
> you might be right in theory.
> In practice, this feature is used in so many codebases that it might be
> worth standardizing.
> And what I propose is a simple way to do it. I think it is even simpler
> like that than an attribute (because we cannot talk properly about inlini=
ng
> within the standard).
>

The inline keyword has changed meaning over the lifetime of c++. Once upon
a time it means "please inline this unless it's a daft idea". Over time it
became apparent that was not required or desirable. inline changed meaning
to mean (in reality) "let me define this in a header file". Still not a
great keyword as it still doesn't imbue *semantic meaning*. It merely
dances around a common implementation details of compilers. __forceinline
was a compiler-specific optimisation which was introduced to overcome
history deficiencies in optimisers - as a community we were still learning.
We (I) used to use asm("") a lot too. Not so much these days.

If anything, inline should probably be a pragma or an [[attribute]] rather
than a keyword. But history is history.

Returning the result of alloca, and extending the caller's stack frame in
magical ways is very much in the realm of implementation details, not *sema=
ntic
meaning*.

Frankly though, if we're going to use alloca (stack storage being used for
something it should not be used for), why not use an alloca-heap and
provide a mechanism to deliver objects from it?

We already have all the machinery for this. The thing you return can be
implemented in terms of a std::unique_ptr with custom deleter. The
alloca-heap can be thread_local if required to eliminate fence-induced
delays.

But then again, why? If we really want such fine-grained control over
lifetimes of variables used by a function, simply pass the function a
context object that contains (perhaps opaquely) the variables. Or implement
the function as a member of the context object.

We can already achieve the optimisations you want while expressing semantic
intent.

eg:

for(auto fooContext =3D Foo() ; maybe() ; )
{
  auto& bar =3D fooContext.barPrep();
  makeUseOf(bar);
}

AFAIR the intent was to lengthen the lifetime of storage used in barPrep -
that's done. Foo can be implemented in whatever "optimising" way the
developer wishes. Using existing language features.

> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e2200f64-c7f=
2-4360-aed9-2e0acbaaea77%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e2200f64-c7=
f2-4360-aed9-2e0acbaaea77%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hb0vOWeQLWq_XznAzOoHz%3DrRNnWu4-93f0hB1kCV=
Rh58A%40mail.gmail.com.

--000000000000e1ed700570c94238
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu=
, 12 Jul 2018 at 09:55, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hod=
ges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 Jul 201=
8 at 03:34, Magnus Fromreide &lt;<a rel=3D"nofollow">ma...@lysator.liu.se</=
a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Jul 11, 2018 =
at 08:26:44AM -0700, <a rel=3D"nofollow">floria...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div></div></div></blockquote><d=
iv><br></div><div>Simple, I already did.</div><div>The callee scope is the =
same as the caller scope. perdiod.</div><div>All the bizareness are handled=
 by this simple rule.</div><div>We could enforce more: like the definition =
must be visible, inline! recursion is not allowed, taking a pointer to such=
 a functions is not allowed...<br></div><div> <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br=
></div><div>b) how would you teach it?</div></div></div></blockquote><div><=
br></div><div>How do you teach macros?<br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><=
div><br></div><div>c) why do you want to return a string_view here (a.k.a. =
dangling references mk 2) when you could simply return the string?</div></d=
iv></div></blockquote><div><br></div><div>If you need to chain functions, i=
t can become clearer returning directly the non-owning wrapper, especially =
if the conversion between the actual object and the non owning wrapper is n=
ot automatic (std::md_span?).</div><div>But I have to say, it&#39;s a small=
 motivation.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>I&#39;m=
 still waiting for someone to post a real motivating use case. So far none =
have been forthcoming. Frankly this is unsurprising. Some feature ideas are=
 simply not destined to survive birth.</div><div>=C2=A0</div></div></div></=
blockquote><div><br></div><div>I already post a valid use case I needed qui=
te a lot: &quot;returning&quot; runtime sized objects.</div><div>Even if yo=
u had VLAs, it would still not be possible to return them, only a view on i=
t. So the only way to have this working is the allocated space must outlive=
 the callee.</div><div>And alloca might not be part of the C++ standard, it=
 is part of POSIX, hence is supported by most platforms (it is also support=
ed on windows).</div><div>So it is possible (and easy) to write portable co=
de using alloca. But as you cannot really return the allocated space from a=
lloca, you need to either do heap allocations (slow), or rely on macros (ba=
d).</div><div>And this inline! would be a big step forward to use such mech=
anism.</div><div><br></div><div>You could argue it would be better to stand=
ardize runtime sized objects, and I would agree. But the cost of standardiz=
ing such objects is extremely high, especially if you allow to return such =
objects.</div><div>My proposal is the opposite: it is simple to standardize=
/implement, while still being useful.<br></div><div><br></div><div>You did =
not even try to say why it is bad. You just said it is somehow possible now=
 (except the part with alloca, which is my main use case for that), but it =
requires more lines, is more cryptic to read...</div><div><br></div><div>I =
don&#39;t say what I propose should defenitely go into the standard. It is =
not perfect and I know it. But I answered clearly to all your objections, a=
nd you don&#39;t really have valid arguments against it.</div><div>So pleas=
e take time to consider everything I said before writing a reply, otherwise=
 your might repeat objections I already answered without any added value.</=
div><div><br></div><div>Also, don&#39;t forget the start point: a way to ha=
ve forced inlining in the laguage using the terms of the language itself.</=
div><div>You might disagree that it is useful to standardize forced inlinin=
g, and you might be right in theory.</div><div>In practice, this feature is=
 used in so many codebases that it might be worth standardizing.</div><div>=
And what I propose is a simple way to do it. I think it is even simpler lik=
e that than an attribute (because we cannot talk properly about inlining wi=
thin the standard).<br></div></div></blockquote><div><br></div><div>The inl=
ine keyword has changed meaning over the lifetime of c++. Once upon a time =
it means &quot;please inline this unless it&#39;s a daft idea&quot;. Over t=
ime it became apparent that was not required or desirable. inline changed m=
eaning to mean (in reality) &quot;let me define this in a header file&quot;=
.. Still not a great keyword as it still doesn&#39;t imbue <i>semantic meani=
ng</i>. It merely dances around a common implementation details of compiler=
s. __forceinline was a compiler-specific optimisation which was introduced =
to overcome history deficiencies in optimisers - as a community we were sti=
ll learning. We (I) used to use asm(&quot;&quot;) a lot too. Not so much th=
ese days.=C2=A0</div><div><br></div><div>If anything, inline should probabl=
y be a pragma or an [[attribute]] rather than a keyword. But history is his=
tory.</div><div><br></div><div>Returning the result of alloca, and extendin=
g the caller&#39;s stack frame in magical ways is very much in the realm of=
 implementation details, not <i>semantic meaning</i>.</div><div><br></div><=
div>Frankly though, if we&#39;re going to use alloca (stack storage being u=
sed for something it should not be used for), why not use an alloca-heap an=
d provide a mechanism to deliver objects from it?</div><div><br></div><div>=
We already have all the machinery for this. The thing you return can be imp=
lemented in terms of a std::unique_ptr with custom deleter. The alloca-heap=
 can be thread_local if required to eliminate fence-induced delays.</div><d=
iv><br></div><div>But then again, why? If we really want such fine-grained =
control over lifetimes of variables used by a function, simply pass the fun=
ction a context object that contains (perhaps opaquely) the variables. Or i=
mplement the function as a member of the context object.=C2=A0</div><div><b=
r></div><div>We can already achieve the optimisations you want while expres=
sing semantic intent.</div><div><br></div><div>eg:</div><div><br></div><div=
><span style=3D"font-family:monospace,monospace">for(</span><span style=3D"=
font-family:monospace,monospace">auto fooContext =3D Foo() ;=C2=A0</span><s=
pan style=3D"font-family:monospace,monospace">maybe() ; )</span><br></div><=
div><font face=3D"monospace, monospace">{</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 auto&amp; bar =3D fooContext.barPrep();</font></=
div><div><font face=3D"monospace, monospace">=C2=A0 makeUseOf(bar);</font><=
/div><div><font face=3D"monospace, monospace">}</font></div><div>=C2=A0</di=
v><div>AFAIR the intent was to lengthen the lifetime of storage used in bar=
Prep - that&#39;s done. Foo can be implemented in whatever &quot;optimising=
&quot; way the developer wishes. Using existing language features.</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e2200f64-c7f2-4360-aed9-2e0acbaaea77%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e2200f64-c7f2-=
4360-aed9-2e0acbaaea77%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hb0vOWeQLWq_XznAzOoHz%3DrRNnWu4=
-93f0hB1kCVRh58A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hb0vOWeQL=
Wq_XznAzOoHz%3DrRNnWu4-93f0hB1kCVRh58A%40mail.gmail.com</a>.<br />

--000000000000e1ed700570c94238--

.


Author: florian.csdt@gmail.com
Date: Thu, 12 Jul 2018 03:02:35 -0700 (PDT)
Raw View
------=_Part_134649_1867405759.1531389755547
Content-Type: multipart/alternative;
 boundary="----=_Part_134650_218611035.1531389755548"

------=_Part_134650_218611035.1531389755548
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le jeudi 12 juillet 2018 10:36:38 UTC+2, Richard Hodges a =C3=A9crit :
>
>
>
> On Thu, 12 Jul 2018 at 09:55, <floria...@gmail.com <javascript:>> wrote:
>
>>
>>
>> Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit :
>>>
>>>
>>>
>>> On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <ma...@lysator.liu.se>=
=20
>>> wrote:
>>>
>>>> On Wed, Jul 11, 2018 at 08:26:44AM -0700, floria...@gmail.com wrote:
>>>> >=20
>>>> >=20
>>>> > >
>>>> > > And if it could do that, why not just let the names be accessible=
=20
>>>> too? If=20
>>>> > > we're relying on the existence of some objects, then rely on it=20
>>>> already.=20
>>>> > > And if we're going that far, why not allow the `inline!` function=
=20
>>>> be able=20
>>>> > > to return *for* its caller rather than *to* its caller? Or affect=
=20
>>>> its=20
>>>> > > caller in other ways.
>>>> > >
>>>> > > You can see that we're quickly moving away from being a mere=20
>>>> "function"=20
>>>> > > and becoming something else: a named series of statements that get=
=20
>>>> > > copy-pasted into code. That might be a useful feature or a=20
>>>> confusing one.=20
>>>> > > But this half-state between them that you propose is exactly that:=
=20
>>>> a=20
>>>> > > half-state. Neither one thing nor the other, the construct is only=
=20
>>>> useful=20
>>>> > > in a trivial number of instances.
>>>> > >
>>>> >=20
>>>> >  @Nicol:
>>>> > Here, you're completely right: those are not really functions anymor=
e.
>>>> >=20
>>>> > However, I would avoid putting names in the caller scope: this more=
=20
>>>> > annoying than it is solving issues.
>>>> > Keeping temporaries because they are referenced elsewhere would be=
=20
>>>> the main=20
>>>> > goal.
>>>>
>>>> I would say it was a novel but peculiar way to introduce anonymous=20
>>>> variables.
>>>>
>>>> inline! std::string_view makeFoo()
>>>> {
>>>>   std::string mAnon(initialize());
>>>>   return mAnon;
>>>> }
>>>>
>>>> Thanks to the inline! the string_view is valid in the returned context=
..=20
>>>
>>>
>>> This is adding a cryptic language feature in order to carry a dependenc=
y=20
>>> through a reference in a hidden way. It is the exact opposite of all th=
e=20
>>> good things that have happened to c++ since 2011. Value semantics, good=
..=20
>>> Tidying up after dangling references, bad.
>>>
>>> Questions:
>>>
>>> a) how would you express this bizzareness in the standard?
>>>
>>
>> Simple, I already did.
>> The callee scope is the same as the caller scope. perdiod.
>> All the bizareness are handled by this simple rule.
>> We could enforce more: like the definition must be visible, inline!=20
>> recursion is not allowed, taking a pointer to such a functions is not=20
>> allowed...
>>
>>
>>> b) how would you teach it?
>>>
>>
>> How do you teach macros?
>> =20
>>
>>>
>>> c) why do you want to return a string_view here (a.k.a. dangling=20
>>> references mk 2) when you could simply return the string?
>>>
>>
>> If you need to chain functions, it can become clearer returning directly=
=20
>> the non-owning wrapper, especially if the conversion between the actual=
=20
>> object and the non owning wrapper is not automatic (std::md_span?).
>> But I have to say, it's a small motivation.
>> =20
>>
>>>
>>> I'm still waiting for someone to post a real motivating use case. So fa=
r=20
>>> none have been forthcoming. Frankly this is unsurprising. Some feature=
=20
>>> ideas are simply not destined to survive birth.
>>> =20
>>>
>>
>> I already post a valid use case I needed quite a lot: "returning" runtim=
e=20
>> sized objects.
>> Even if you had VLAs, it would still not be possible to return them, onl=
y=20
>> a view on it. So the only way to have this working is the allocated spac=
e=20
>> must outlive the callee.
>> And alloca might not be part of the C++ standard, it is part of POSIX,=
=20
>> hence is supported by most platforms (it is also supported on windows).
>> So it is possible (and easy) to write portable code using alloca. But as=
=20
>> you cannot really return the allocated space from alloca, you need to=20
>> either do heap allocations (slow), or rely on macros (bad).
>> And this inline! would be a big step forward to use such mechanism.
>>
>> You could argue it would be better to standardize runtime sized objects,=
=20
>> and I would agree. But the cost of standardizing such objects is extreme=
ly=20
>> high, especially if you allow to return such objects.
>> My proposal is the opposite: it is simple to standardize/implement, whil=
e=20
>> still being useful.
>>
>> You did not even try to say why it is bad. You just said it is somehow=
=20
>> possible now (except the part with alloca, which is my main use case for=
=20
>> that), but it requires more lines, is more cryptic to read...
>>
>> I don't say what I propose should defenitely go into the standard. It is=
=20
>> not perfect and I know it. But I answered clearly to all your objections=
,=20
>> and you don't really have valid arguments against it.
>> So please take time to consider everything I said before writing a reply=
,=20
>> otherwise your might repeat objections I already answered without any ad=
ded=20
>> value.
>>
>> Also, don't forget the start point: a way to have forced inlining in the=
=20
>> laguage using the terms of the language itself.
>> You might disagree that it is useful to standardize forced inlining, and=
=20
>> you might be right in theory.
>> In practice, this feature is used in so many codebases that it might be=
=20
>> worth standardizing.
>> And what I propose is a simple way to do it. I think it is even simpler=
=20
>> like that than an attribute (because we cannot talk properly about inlin=
ing=20
>> within the standard).
>>
>
> The inline keyword has changed meaning over the lifetime of c++. Once upo=
n=20
> a time it means "please inline this unless it's a daft idea". Over time i=
t=20
> became apparent that was not required or desirable. inline changed meanin=
g=20
> to mean (in reality) "let me define this in a header file". Still not a=
=20
> great keyword as it still doesn't imbue *semantic meaning*. It merely=20
> dances around a common implementation details of compilers. __forceinline=
=20
> was a compiler-specific optimisation which was introduced to overcome=20
> history deficiencies in optimisers - as a community we were still learnin=
g.=20
> We (I) used to use asm("") a lot too. Not so much these days.=20
>

The old meaning of inline was inherited from C. So it does not really apply=
=20
to C++ as the specification is different, and rely on an abstract machine.=
=20
But that's not really relevant to the discussion anyway.
The meaning has evolved because we needed a way to express the new idea,=20
and inline was close enough, so was simpler to repurpose this keyword=20
instead of creating a new one. This has nothing to do with implementation.

Forced inlining is still used a lot, and in majority for good reasons:=20
optimizing compilers are not almighty and never will. We will always need=
=20
force inline and asm. Less and less, I agree, but still.


> If anything, inline should probably be a pragma or an [[attribute]] rathe=
r=20
> than a keyword. But history is history.
>

Not with the current meaning. Actually, I think all functions should be=20
"inline" and the keyword deprecated. Most already are by default (templates=
=20
and in-class defined methods).
=20

>
> Returning the result of alloca, and extending the caller's stack frame in=
=20
> magical ways is very much in the realm of implementation details, not *se=
mantic=20
> meaning*.
>

It is an implementation detail to do something that is not currently=20
possible to do efficiently, ie: returning a runtime sized object. The only=
=20
way to do it currently is with heap allocation, no matter what.
=20

>
> Frankly though, if we're going to use alloca (stack storage being used fo=
r=20
> something it should not be used for), why not use an alloca-heap and=20
> provide a mechanism to deliver objects from it?
>

Because if you want the speed of alloca, you want the speed of alloca, not=
=20
something slower. What you propose will be slower (faster than regular heap=
=20
allocation, though).
=20

>
> We already have all the machinery for this. The thing you return can be=
=20
> implemented in terms of a std::unique_ptr with custom deleter. The=20
> alloca-heap can be thread_local if required to eliminate fence-induced=20
> delays.
>

Not as efficient as alloca is. You cannot beat alloca.
=20

>
> But then again, why? If we really want such fine-grained control over=20
> lifetimes of variables used by a function, simply pass the function a=20
> context object that contains (perhaps opaquely) the variables. Or impleme=
nt=20
> the function as a member of the context object.=20
>
> We can already achieve the optimisations you want while expressing=20
> semantic intent.
>
> eg:
>
> for(auto fooContext =3D Foo() ; maybe() ; )
> {
>   auto& bar =3D fooContext.barPrep();
>   makeUseOf(bar);
> }
>

But this cannot work with runtime sized objects. If you have a proposal for=
=20
runtime sized object that allows to return such objects that is almost=20
ready, then fine. All my remarks don't apply anymore. But that's not the=20
case.
And standardizing runtime sized objects, while completely worthwile, will=
=20
be a very long and hard task.
What I propose is a simple workaround that will be able to handle a bunch=
=20
of useful cases.

Also, if you don't need to be as fast as what I'm looking for, then fine,=
=20
you don't need that, but I still do, and I'm not the only one.
=20

> =20
> AFAIR the intent was to lengthen the lifetime of storage used in barPrep =
-=20
> that's done. Foo can be implemented in whatever "optimising" way the=20
> developer wishes. Using existing language features.
>

As long as you don't need runtime sized objects, yes.
Runtime sized objects will be a deal breaker, especially for HPC. This=20
would avoid the need to preallocate enough memory beforehand and pass those=
=20
to every single function that needs it, and without relying only TLS.
But currently, it is not possible to have this, and it will come at great=
=20
standardizing costs.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452%40isocpp.or=
g.

------=_Part_134650_218611035.1531389755548
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 10:36:38 UTC+2, Richard H=
odges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 =
Jul 2018 at 09:55, &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"kN_0o731CAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">floria...@gmail.com</a>&gt; wrote:<br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 09:05:5=
1 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr=
">On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide &lt;<a rel=3D"nofollow">ma=
....@lysator.liu.se</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">O=
n Wed, Jul 11, 2018 at 08:26:44AM -0700, <a rel=3D"nofollow">floria...@gmai=
l.com</a> wrote:<br>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div></div></div></blockquote><d=
iv><br></div><div>Simple, I already did.</div><div>The callee scope is the =
same as the caller scope. perdiod.</div><div>All the bizareness are handled=
 by this simple rule.</div><div>We could enforce more: like the definition =
must be visible, inline! recursion is not allowed, taking a pointer to such=
 a functions is not allowed...<br></div><div> <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br=
></div><div>b) how would you teach it?</div></div></div></blockquote><div><=
br></div><div>How do you teach macros?<br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><=
div><br></div><div>c) why do you want to return a string_view here (a.k.a. =
dangling references mk 2) when you could simply return the string?</div></d=
iv></div></blockquote><div><br></div><div>If you need to chain functions, i=
t can become clearer returning directly the non-owning wrapper, especially =
if the conversion between the actual object and the non owning wrapper is n=
ot automatic (std::md_span?).</div><div>But I have to say, it&#39;s a small=
 motivation.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>I&#39;m=
 still waiting for someone to post a real motivating use case. So far none =
have been forthcoming. Frankly this is unsurprising. Some feature ideas are=
 simply not destined to survive birth.</div><div>=C2=A0</div></div></div></=
blockquote><div><br></div><div>I already post a valid use case I needed qui=
te a lot: &quot;returning&quot; runtime sized objects.</div><div>Even if yo=
u had VLAs, it would still not be possible to return them, only a view on i=
t. So the only way to have this working is the allocated space must outlive=
 the callee.</div><div>And alloca might not be part of the C++ standard, it=
 is part of POSIX, hence is supported by most platforms (it is also support=
ed on windows).</div><div>So it is possible (and easy) to write portable co=
de using alloca. But as you cannot really return the allocated space from a=
lloca, you need to either do heap allocations (slow), or rely on macros (ba=
d).</div><div>And this inline! would be a big step forward to use such mech=
anism.</div><div><br></div><div>You could argue it would be better to stand=
ardize runtime sized objects, and I would agree. But the cost of standardiz=
ing such objects is extremely high, especially if you allow to return such =
objects.</div><div>My proposal is the opposite: it is simple to standardize=
/implement, while still being useful.<br></div><div><br></div><div>You did =
not even try to say why it is bad. You just said it is somehow possible now=
 (except the part with alloca, which is my main use case for that), but it =
requires more lines, is more cryptic to read...</div><div><br></div><div>I =
don&#39;t say what I propose should defenitely go into the standard. It is =
not perfect and I know it. But I answered clearly to all your objections, a=
nd you don&#39;t really have valid arguments against it.</div><div>So pleas=
e take time to consider everything I said before writing a reply, otherwise=
 your might repeat objections I already answered without any added value.</=
div><div><br></div><div>Also, don&#39;t forget the start point: a way to ha=
ve forced inlining in the laguage using the terms of the language itself.</=
div><div>You might disagree that it is useful to standardize forced inlinin=
g, and you might be right in theory.</div><div>In practice, this feature is=
 used in so many codebases that it might be worth standardizing.</div><div>=
And what I propose is a simple way to do it. I think it is even simpler lik=
e that than an attribute (because we cannot talk properly about inlining wi=
thin the standard).<br></div></div></blockquote><div><br></div><div>The inl=
ine keyword has changed meaning over the lifetime of c++. Once upon a time =
it means &quot;please inline this unless it&#39;s a daft idea&quot;. Over t=
ime it became apparent that was not required or desirable. inline changed m=
eaning to mean (in reality) &quot;let me define this in a header file&quot;=
.. Still not a great keyword as it still doesn&#39;t imbue <i>semantic meani=
ng</i>. It merely dances around a common implementation details of compiler=
s. __forceinline was a compiler-specific optimisation which was introduced =
to overcome history deficiencies in optimisers - as a community we were sti=
ll learning. We (I) used to use asm(&quot;&quot;) a lot too. Not so much th=
ese days.=C2=A0</div></div></div></blockquote><div><br></div><div>The old m=
eaning of inline was inherited from C. So it does not really apply to C++ a=
s the specification is different, and rely on an abstract machine. But that=
&#39;s not really relevant to the discussion anyway.</div><div>The meaning =
has evolved because we needed a way to express the new idea, and inline was=
 close enough, so was simpler to repurpose this keyword instead of creating=
 a new one. This has nothing to do with implementation.</div><div><br></div=
><div>Forced inlining is still used a lot, and in majority for good reasons=
: optimizing compilers are not almighty and never will. We will always need=
 force inline and asm. Less and less, I agree, but still.<br></div><div> <b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div =
class=3D"gmail_quote"><div><br></div><div>If anything, inline should probab=
ly be a pragma or an [[attribute]] rather than a keyword. But history is hi=
story.</div></div></div></blockquote><div><br></div><div>Not with the curre=
nt meaning. Actually, I think all functions should be &quot;inline&quot; an=
d the keyword deprecated. Most already are by default (templates and in-cla=
ss defined methods).<br></div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div=
><div>Returning the result of alloca, and extending the caller&#39;s stack =
frame in magical ways is very much in the realm of implementation details, =
not <i>semantic meaning</i>.</div></div></div></blockquote><div><br></div><=
div>It is an implementation detail to do something that is not currently po=
ssible to do efficiently, ie: returning a runtime sized object. The only wa=
y to do it currently is with heap allocation, no matter what.<br></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div class=3D"gmail_quote"><div><br></div><div>Frankly though, if we&#39;re=
 going to use alloca (stack storage being used for something it should not =
be used for), why not use an alloca-heap and provide a mechanism to deliver=
 objects from it?</div></div></div></blockquote><div><br></div><div>Because=
 if you want the speed of alloca, you want the speed of alloca, not somethi=
ng slower. What you propose will be slower (faster than regular heap alloca=
tion, though).<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>=
We already have all the machinery for this. The thing you return can be imp=
lemented in terms of a std::unique_ptr with custom deleter. The alloca-heap=
 can be thread_local if required to eliminate fence-induced delays.</div></=
div></div></blockquote><div><br></div><div>Not as efficient as alloca is. Y=
ou cannot beat alloca.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></d=
iv><div>But then again, why? If we really want such fine-grained control ov=
er lifetimes of variables used by a function, simply pass the function a co=
ntext object that contains (perhaps opaquely) the variables. Or implement t=
he function as a member of the context object.=C2=A0</div><div><br></div><d=
iv>We can already achieve the optimisations you want while expressing seman=
tic intent.</div><div><br></div><div>eg:</div><div><br></div><div><span sty=
le=3D"font-family:monospace,monospace">for(</span><span style=3D"font-famil=
y:monospace,monospace">auto fooContext =3D Foo() ;=C2=A0</span><span style=
=3D"font-family:monospace,monospace">maybe() ; )</span><br></div><div><font=
 face=3D"monospace, monospace">{</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 auto&amp; bar =3D fooContext.barPrep();</font></div><div>=
<font face=3D"monospace, monospace">=C2=A0 makeUseOf(bar);</font></div><div=
><font face=3D"monospace, monospace">}</font></div></div></div></blockquote=
><div><br></div><div>But this cannot work with runtime sized objects. If yo=
u have a proposal for runtime sized object that allows to return such objec=
ts that is almost ready, then fine. All my remarks don&#39;t apply anymore.=
 But that&#39;s not the case.</div><div>And standardizing runtime sized obj=
ects, while completely worthwile, will be a very long and hard task.</div><=
div>What I propose is a simple workaround that will be able to handle a bun=
ch of useful cases.</div><div><br></div><div>Also, if you don&#39;t need to=
 be as fast as what I&#39;m looking for, then fine, you don&#39;t need that=
, but I still do, and I&#39;m not the only one.<br></div><div>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"=
gmail_quote"><div>=C2=A0</div><div>AFAIR the intent was to lengthen the lif=
etime of storage used in barPrep - that&#39;s done. Foo can be implemented =
in whatever &quot;optimising&quot; way the developer wishes. Using existing=
 language features.</div></div></div></blockquote><div><br></div><div>As lo=
ng as you don&#39;t need runtime sized objects, yes.</div><div>Runtime size=
d objects will be a deal breaker, especially for HPC. This would avoid the =
need to preallocate enough memory beforehand and pass those to every single=
 function that needs it, and without relying only TLS.</div><div>But curren=
tly, it is not possible to have this, and it will come at great standardizi=
ng costs.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452=
%40isocpp.org</a>.<br />

------=_Part_134650_218611035.1531389755548--

------=_Part_134649_1867405759.1531389755547--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Thu, 12 Jul 2018 12:50:40 +0200
Raw View
--000000000000030ee70570cb2330
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Thu, 12 Jul 2018 at 12:02, <florian.csdt@gmail.com> wrote:

>
>
> Le jeudi 12 juillet 2018 10:36:38 UTC+2, Richard Hodges a =C3=A9crit :
>>
>>
>>
>> On Thu, 12 Jul 2018 at 09:55, <floria...@gmail.com> wrote:
>>
>>>
>>>
>>> Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit :
>>>>
>>>>
>>>>
>>>> On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <ma...@lysator.liu.se>
>>>> wrote:
>>>>
>>>>> On Wed, Jul 11, 2018 at 08:26:44AM -0700, floria...@gmail.com wrote:
>>>>> >
>>>>> >
>>>>> > >
>>>>> > > And if it could do that, why not just let the names be accessible
>>>>> too? If
>>>>> > > we're relying on the existence of some objects, then rely on it
>>>>> already.
>>>>> > > And if we're going that far, why not allow the `inline!` function
>>>>> be able
>>>>> > > to return *for* its caller rather than *to* its caller? Or affect
>>>>> its
>>>>> > > caller in other ways.
>>>>> > >
>>>>> > > You can see that we're quickly moving away from being a mere
>>>>> "function"
>>>>> > > and becoming something else: a named series of statements that ge=
t
>>>>> > > copy-pasted into code. That might be a useful feature or a
>>>>> confusing one.
>>>>> > > But this half-state between them that you propose is exactly that=
:
>>>>> a
>>>>> > > half-state. Neither one thing nor the other, the construct is onl=
y
>>>>> useful
>>>>> > > in a trivial number of instances.
>>>>> > >
>>>>> >
>>>>> >  @Nicol:
>>>>> > Here, you're completely right: those are not really functions
>>>>> anymore.
>>>>> >
>>>>> > However, I would avoid putting names in the caller scope: this more
>>>>> > annoying than it is solving issues.
>>>>> > Keeping temporaries because they are referenced elsewhere would be
>>>>> the main
>>>>> > goal.
>>>>>
>>>>> I would say it was a novel but peculiar way to introduce anonymous
>>>>> variables.
>>>>>
>>>>> inline! std::string_view makeFoo()
>>>>> {
>>>>>   std::string mAnon(initialize());
>>>>>   return mAnon;
>>>>> }
>>>>>
>>>>> Thanks to the inline! the string_view is valid in the returned
>>>>> context.
>>>>
>>>>
>>>> This is adding a cryptic language feature in order to carry a
>>>> dependency through a reference in a hidden way. It is the exact opposi=
te of
>>>> all the good things that have happened to c++ since 2011. Value semant=
ics,
>>>> good. Tidying up after dangling references, bad.
>>>>
>>>> Questions:
>>>>
>>>> a) how would you express this bizzareness in the standard?
>>>>
>>>
>>> Simple, I already did.
>>> The callee scope is the same as the caller scope. perdiod.
>>> All the bizareness are handled by this simple rule.
>>> We could enforce more: like the definition must be visible, inline!
>>> recursion is not allowed, taking a pointer to such a functions is not
>>> allowed...
>>>
>>>
>>>> b) how would you teach it?
>>>>
>>>
>>> How do you teach macros?
>>>
>>>
>>>>
>>>> c) why do you want to return a string_view here (a.k.a. dangling
>>>> references mk 2) when you could simply return the string?
>>>>
>>>
>>> If you need to chain functions, it can become clearer returning directl=
y
>>> the non-owning wrapper, especially if the conversion between the actual
>>> object and the non owning wrapper is not automatic (std::md_span?).
>>> But I have to say, it's a small motivation.
>>>
>>>
>>>>
>>>> I'm still waiting for someone to post a real motivating use case. So
>>>> far none have been forthcoming. Frankly this is unsurprising. Some fea=
ture
>>>> ideas are simply not destined to survive birth.
>>>>
>>>>
>>>
>>> I already post a valid use case I needed quite a lot: "returning"
>>> runtime sized objects.
>>> Even if you had VLAs, it would still not be possible to return them,
>>> only a view on it. So the only way to have this working is the allocate=
d
>>> space must outlive the callee.
>>> And alloca might not be part of the C++ standard, it is part of POSIX,
>>> hence is supported by most platforms (it is also supported on windows).
>>> So it is possible (and easy) to write portable code using alloca. But a=
s
>>> you cannot really return the allocated space from alloca, you need to
>>> either do heap allocations (slow), or rely on macros (bad).
>>> And this inline! would be a big step forward to use such mechanism.
>>>
>>> You could argue it would be better to standardize runtime sized objects=
,
>>> and I would agree. But the cost of standardizing such objects is extrem=
ely
>>> high, especially if you allow to return such objects.
>>> My proposal is the opposite: it is simple to standardize/implement,
>>> while still being useful.
>>>
>>> You did not even try to say why it is bad. You just said it is somehow
>>> possible now (except the part with alloca, which is my main use case fo=
r
>>> that), but it requires more lines, is more cryptic to read...
>>>
>>> I don't say what I propose should defenitely go into the standard. It i=
s
>>> not perfect and I know it. But I answered clearly to all your objection=
s,
>>> and you don't really have valid arguments against it.
>>> So please take time to consider everything I said before writing a
>>> reply, otherwise your might repeat objections I already answered withou=
t
>>> any added value.
>>>
>>> Also, don't forget the start point: a way to have forced inlining in th=
e
>>> laguage using the terms of the language itself.
>>> You might disagree that it is useful to standardize forced inlining, an=
d
>>> you might be right in theory.
>>> In practice, this feature is used in so many codebases that it might be
>>> worth standardizing.
>>> And what I propose is a simple way to do it. I think it is even simpler
>>> like that than an attribute (because we cannot talk properly about inli=
ning
>>> within the standard).
>>>
>>
>> The inline keyword has changed meaning over the lifetime of c++. Once
>> upon a time it means "please inline this unless it's a daft idea". Over
>> time it became apparent that was not required or desirable. inline chang=
ed
>> meaning to mean (in reality) "let me define this in a header file". Stil=
l
>> not a great keyword as it still doesn't imbue *semantic meaning*. It
>> merely dances around a common implementation details of compilers.
>> __forceinline was a compiler-specific optimisation which was introduced =
to
>> overcome history deficiencies in optimisers - as a community we were sti=
ll
>> learning. We (I) used to use asm("") a lot too. Not so much these days.
>>
>
> The old meaning of inline was inherited from C. So it does not really
> apply to C++ as the specification is different, and rely on an abstract
> machine. But that's not really relevant to the discussion anyway.
> The meaning has evolved because we needed a way to express the new idea,
> and inline was close enough, so was simpler to repurpose this keyword
> instead of creating a new one. This has nothing to do with implementation=
..
>
> Forced inlining is still used a lot, and in majority for good reasons:
> optimizing compilers are not almighty and never will. We will always need
> force inline and asm. Less and less, I agree, but still.
>
>
>> If anything, inline should probably be a pragma or an [[attribute]]
>> rather than a keyword. But history is history.
>>
>
> Not with the current meaning. Actually, I think all functions should be
> "inline" and the keyword deprecated. Most already are by default (templat=
es
> and in-class defined methods).
>
>
>>
>> Returning the result of alloca, and extending the caller's stack frame i=
n
>> magical ways is very much in the realm of implementation details, not *s=
emantic
>> meaning*.
>>
>
> It is an implementation detail to do something that is not currently
> possible to do efficiently, ie: returning a runtime sized object. The onl=
y
> way to do it currently is with heap allocation, no matter what.
>
>
>>
>> Frankly though, if we're going to use alloca (stack storage being used
>> for something it should not be used for), why not use an alloca-heap and
>> provide a mechanism to deliver objects from it?
>>
>
> Because if you want the speed of alloca, you want the speed of alloca, no=
t
> something slower. What you propose will be slower (faster than regular he=
ap
> allocation, though).
>
>
>>
>> We already have all the machinery for this. The thing you return can be
>> implemented in terms of a std::unique_ptr with custom deleter. The
>> alloca-heap can be thread_local if required to eliminate fence-induced
>> delays.
>>
>
> Not as efficient as alloca is. You cannot beat alloca.
>
>
>>
>> But then again, why? If we really want such fine-grained control over
>> lifetimes of variables used by a function, simply pass the function a
>> context object that contains (perhaps opaquely) the variables. Or implem=
ent
>> the function as a member of the context object.
>>
>> We can already achieve the optimisations you want while expressing
>> semantic intent.
>>
>> eg:
>>
>> for(auto fooContext =3D Foo() ; maybe() ; )
>> {
>>   auto& bar =3D fooContext.barPrep();
>>   makeUseOf(bar);
>> }
>>
>
> But this cannot work with runtime sized objects. If you have a proposal
> for runtime sized object that allows to return such objects that is almos=
t
> ready, then fine. All my remarks don't apply anymore. But that's not the
> case.
> And standardizing runtime sized objects, while completely worthwile, will
> be a very long and hard task.
> What I propose is a simple workaround that will be able to handle a bunch
> of useful cases.
>
> Also, if you don't need to be as fast as what I'm looking for, then fine,
> you don't need that, but I still do, and I'm not the only one.
>
>
>>
>> AFAIR the intent was to lengthen the lifetime of storage used in barPrep
>> - that's done. Foo can be implemented in whatever "optimising" way the
>> developer wishes. Using existing language features.
>>
>
> As long as you don't need runtime sized objects, yes.
> Runtime sized objects will be a deal breaker, especially for HPC. This
> would avoid the need to preallocate enough memory beforehand and pass tho=
se
> to every single function that needs it, and without relying only TLS.
> But currently, it is not possible to have this, and it will come at great
> standardizing costs.
>

I've worked with HPC and grid computing in computation of value and risk in
exotic derivatives. I am unimpressed with performance-based arguments for
standardising hacks.

If it's really necessary (and it almost never is), we can easily build safe
alloca-like behaviour with a second-stack custom allocator, implemented in
terms of a thread_local second_stack_impl:

struct second_stack_impl
{
  static constexpr std::size_t rounding =3D sizeof(std::uintptr_t); // etc
  static constexpr std::size_t size =3D 1024 * 1024; // or by runtime confi=
g

  std::byte* alloc(std::size_t bytes)
  {
    // round and allocate from second stack,
    // store size
    // return address of allocated data
  }

  void dealloc()
  {
    // recover size from stack top and
    // return to stack
  }

  std::array<std::byte, size> storage;
  std::byte* top =3D storage.data() + size;
};

// gcc uses the fs register to address thread_local data. Zero overhead.
thread_local second_stack_impl second_stack;




> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-024=
0-4130-8918-0b1dbe924452%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-02=
40-4130-8918-0b1dbe924452%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hZi1WzmWFHnQ5bO-uQ1UHG_ba6QHPz1DdFnrzQpJJH=
2zA%40mail.gmail.com.

--000000000000030ee70570cb2330
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu=
, 12 Jul 2018 at 12:02, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 10:36:38 UTC+2, Richard Hod=
ges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 Jul 201=
8 at 09:55, &lt;<a rel=3D"nofollow">floria...@gmail.com</a>&gt; wrote:<br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le jeudi 12 ju=
illet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quot=
e"><div dir=3D"ltr">On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide &lt;<a r=
el=3D"nofollow">ma...@lysator.liu.se</a>&gt; wrote:<br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">On Wed, Jul 11, 2018 at 08:26:44AM -0700, <a rel=3D"nofoll=
ow">floria...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div></div></div></blockquote><d=
iv><br></div><div>Simple, I already did.</div><div>The callee scope is the =
same as the caller scope. perdiod.</div><div>All the bizareness are handled=
 by this simple rule.</div><div>We could enforce more: like the definition =
must be visible, inline! recursion is not allowed, taking a pointer to such=
 a functions is not allowed...<br></div><div> <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br=
></div><div>b) how would you teach it?</div></div></div></blockquote><div><=
br></div><div>How do you teach macros?<br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><=
div><br></div><div>c) why do you want to return a string_view here (a.k.a. =
dangling references mk 2) when you could simply return the string?</div></d=
iv></div></blockquote><div><br></div><div>If you need to chain functions, i=
t can become clearer returning directly the non-owning wrapper, especially =
if the conversion between the actual object and the non owning wrapper is n=
ot automatic (std::md_span?).</div><div>But I have to say, it&#39;s a small=
 motivation.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>I&#39;m=
 still waiting for someone to post a real motivating use case. So far none =
have been forthcoming. Frankly this is unsurprising. Some feature ideas are=
 simply not destined to survive birth.</div><div>=C2=A0</div></div></div></=
blockquote><div><br></div><div>I already post a valid use case I needed qui=
te a lot: &quot;returning&quot; runtime sized objects.</div><div>Even if yo=
u had VLAs, it would still not be possible to return them, only a view on i=
t. So the only way to have this working is the allocated space must outlive=
 the callee.</div><div>And alloca might not be part of the C++ standard, it=
 is part of POSIX, hence is supported by most platforms (it is also support=
ed on windows).</div><div>So it is possible (and easy) to write portable co=
de using alloca. But as you cannot really return the allocated space from a=
lloca, you need to either do heap allocations (slow), or rely on macros (ba=
d).</div><div>And this inline! would be a big step forward to use such mech=
anism.</div><div><br></div><div>You could argue it would be better to stand=
ardize runtime sized objects, and I would agree. But the cost of standardiz=
ing such objects is extremely high, especially if you allow to return such =
objects.</div><div>My proposal is the opposite: it is simple to standardize=
/implement, while still being useful.<br></div><div><br></div><div>You did =
not even try to say why it is bad. You just said it is somehow possible now=
 (except the part with alloca, which is my main use case for that), but it =
requires more lines, is more cryptic to read...</div><div><br></div><div>I =
don&#39;t say what I propose should defenitely go into the standard. It is =
not perfect and I know it. But I answered clearly to all your objections, a=
nd you don&#39;t really have valid arguments against it.</div><div>So pleas=
e take time to consider everything I said before writing a reply, otherwise=
 your might repeat objections I already answered without any added value.</=
div><div><br></div><div>Also, don&#39;t forget the start point: a way to ha=
ve forced inlining in the laguage using the terms of the language itself.</=
div><div>You might disagree that it is useful to standardize forced inlinin=
g, and you might be right in theory.</div><div>In practice, this feature is=
 used in so many codebases that it might be worth standardizing.</div><div>=
And what I propose is a simple way to do it. I think it is even simpler lik=
e that than an attribute (because we cannot talk properly about inlining wi=
thin the standard).<br></div></div></blockquote><div><br></div><div>The inl=
ine keyword has changed meaning over the lifetime of c++. Once upon a time =
it means &quot;please inline this unless it&#39;s a daft idea&quot;. Over t=
ime it became apparent that was not required or desirable. inline changed m=
eaning to mean (in reality) &quot;let me define this in a header file&quot;=
.. Still not a great keyword as it still doesn&#39;t imbue <i>semantic meani=
ng</i>. It merely dances around a common implementation details of compiler=
s. __forceinline was a compiler-specific optimisation which was introduced =
to overcome history deficiencies in optimisers - as a community we were sti=
ll learning. We (I) used to use asm(&quot;&quot;) a lot too. Not so much th=
ese days.=C2=A0</div></div></div></blockquote><div><br></div><div>The old m=
eaning of inline was inherited from C. So it does not really apply to C++ a=
s the specification is different, and rely on an abstract machine. But that=
&#39;s not really relevant to the discussion anyway.</div><div>The meaning =
has evolved because we needed a way to express the new idea, and inline was=
 close enough, so was simpler to repurpose this keyword instead of creating=
 a new one. This has nothing to do with implementation.</div><div><br></div=
><div>Forced inlining is still used a lot, and in majority for good reasons=
: optimizing compilers are not almighty and never will. We will always need=
 force inline and asm. Less and less, I agree, but still.<br></div><div> <b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_quote"><div><br></div><div>If anything, inline should probably be=
 a pragma or an [[attribute]] rather than a keyword. But history is history=
..</div></div></div></blockquote><div><br></div><div>Not with the current me=
aning. Actually, I think all functions should be &quot;inline&quot; and the=
 keyword deprecated. Most already are by default (templates and in-class de=
fined methods).<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>Retu=
rning the result of alloca, and extending the caller&#39;s stack frame in m=
agical ways is very much in the realm of implementation details, not <i>sem=
antic meaning</i>.</div></div></div></blockquote><div><br></div><div>It is =
an implementation detail to do something that is not currently possible to =
do efficiently, ie: returning a runtime sized object. The only way to do it=
 currently is with heap allocation, no matter what.<br></div><div>=C2=A0</d=
iv><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 class=3D"g=
mail_quote"><div><br></div><div>Frankly though, if we&#39;re going to use a=
lloca (stack storage being used for something it should not be used for), w=
hy not use an alloca-heap and provide a mechanism to deliver objects from i=
t?</div></div></div></blockquote><div><br></div><div>Because if you want th=
e speed of alloca, you want the speed of alloca, not something slower. What=
 you propose will be slower (faster than regular heap allocation, though).<=
br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>We already have all=
 the machinery for this. The thing you return can be implemented in terms o=
f a std::unique_ptr with custom deleter. The alloca-heap can be thread_loca=
l if required to eliminate fence-induced delays.</div></div></div></blockqu=
ote><div><br></div><div>Not as efficient as alloca is. You cannot beat allo=
ca.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>But then again, =
why? If we really want such fine-grained control over lifetimes of variable=
s used by a function, simply pass the function a context object that contai=
ns (perhaps opaquely) the variables. Or implement the function as a member =
of the context object.=C2=A0</div><div><br></div><div>We can already achiev=
e the optimisations you want while expressing semantic intent.</div><div><b=
r></div><div>eg:</div><div><br></div><div><span style=3D"font-family:monosp=
ace,monospace">for(</span><span style=3D"font-family:monospace,monospace">a=
uto fooContext =3D Foo() ;=C2=A0</span><span style=3D"font-family:monospace=
,monospace">maybe() ; )</span><br></div><div><font face=3D"monospace, monos=
pace">{</font></div><div><font face=3D"monospace, monospace">=C2=A0 auto&am=
p; bar =3D fooContext.barPrep();</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 makeUseOf(bar);</font></div><div><font face=3D"monospace,=
 monospace">}</font></div></div></div></blockquote><div><br></div><div>But =
this cannot work with runtime sized objects. If you have a proposal for run=
time sized object that allows to return such objects that is almost ready, =
then fine. All my remarks don&#39;t apply anymore. But that&#39;s not the c=
ase.</div><div>And standardizing runtime sized objects, while completely wo=
rthwile, will be a very long and hard task.</div><div>What I propose is a s=
imple workaround that will be able to handle a bunch of useful cases.</div>=
<div><br></div><div>Also, if you don&#39;t need to be as fast as what I&#39=
;m looking for, then fine, you don&#39;t need that, but I still do, and I&#=
39;m not the only one.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div>=C2=A0</div>=
<div>AFAIR the intent was to lengthen the lifetime of storage used in barPr=
ep - that&#39;s done. Foo can be implemented in whatever &quot;optimising&q=
uot; way the developer wishes. Using existing language features.</div></div=
></div></blockquote><div><br></div><div>As long as you don&#39;t need runti=
me sized objects, yes.</div><div>Runtime sized objects will be a deal break=
er, especially for HPC. This would avoid the need to preallocate enough mem=
ory beforehand and pass those to every single function that needs it, and w=
ithout relying only TLS.</div><div>But currently, it is not possible to hav=
e this, and it will come at great standardizing costs.<br></div></div></blo=
ckquote><div><br></div><div>I&#39;ve worked with HPC and grid computing in =
computation of value and risk in exotic derivatives. I am unimpressed with =
performance-based arguments for standardising hacks.</div><div><br></div><d=
iv>If it&#39;s really necessary (and it almost never is), we can easily bui=
ld safe alloca-like behaviour with a second-stack custom allocator, impleme=
nted in terms of a thread_local second_stack_impl:</div><div><br></div><div=
><div style=3D"color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><fo=
nt face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,255)">struct<=
/span><span style=3D"color:rgb(0,0,0)"> second_stack_impl</span></font></di=
v><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace"=
>{</font></span></div><div><font face=3D"monospace, monospace"><span style=
=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255)">=C2=A0 stat=
ic</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
0,0,255)">constexpr</span><span style=3D"color:rgb(0,0,0)"> std::size_t rou=
nding =3D </span><span style=3D"color:rgb(0,0,255)">sizeof</span><span styl=
e=3D"color:rgb(0,0,0)">(std::uintptr_t); // etc</span></font></div><div><fo=
nt face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></span><s=
pan style=3D"color:rgb(0,0,255)">=C2=A0 static</span><span style=3D"color:r=
gb(0,0,0)"> </span><span style=3D"color:rgb(0,0,255)">constexpr</span><span=
 style=3D"color:rgb(0,0,0)"> std::size_t size =3D </span><span style=3D"col=
or:rgb(9,136,90)">1024</span><span style=3D"color:rgb(0,0,0)"> * </span><sp=
an style=3D"color:rgb(9,136,90)">1024</span><span style=3D"color:rgb(0,0,0)=
">; // or by runtime config</span></font></div><font face=3D"monospace, mon=
ospace"><br></font><div><span style=3D"color:rgb(0,0,0)"><font face=3D"mono=
space, monospace">=C2=A0 std::byte* alloc(std::size_t bytes)</font></span><=
/div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospa=
ce">=C2=A0 {</font></span></div><div><font face=3D"monospace, monospace"><s=
pan style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,128,0)">=
=C2=A0 =C2=A0 // round and allocate from second stack,</span></font></div><=
div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></=
span><span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // store size</span><=
/font></div><div><font face=3D"monospace, monospace"><span style=3D"color:r=
gb(0,128,0)">=C2=A0 =C2=A0 // return address of allocated data</span></font=
></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monos=
pace">=C2=A0 }</font></span></div><font face=3D"monospace, monospace"><br><=
/font><div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0=
,0)"></span><span style=3D"color:rgb(0,0,255)">=C2=A0 void</span><span styl=
e=3D"color:rgb(0,0,0)"> dealloc()</span></font></div><div><span style=3D"co=
lor:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 {</font></span><=
/div><div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,=
0)"></span><span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // recover size=
 from stack top and </span></font></div><div><font face=3D"monospace, monos=
pace"><span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,12=
8,0)">=C2=A0 =C2=A0 // return to stack</span></font></div><div><span style=
=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 }</font></=
span></div><font face=3D"monospace, monospace"><br></font><div><span style=
=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 std::array=
&lt;std::byte, size&gt; storage;</font></span></div><div><span style=3D"col=
or:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 std::byte* top =
=3D storage.data() + size;</font></span></div><div><span style=3D"color:rgb=
(0,0,0)"><font face=3D"monospace, monospace">};</font></span></div><font fa=
ce=3D"monospace, monospace"><span style=3D"color:rgb(0,128,0);font-size:sma=
ll;background-color:rgb(255,255,254);text-decoration-style:initial;text-dec=
oration-color:initial;float:none;display:inline"><div style=3D"color:rgb(0,=
0,0);background-color:rgb(255,255,254)"><font face=3D"monospace, monospace"=
><span style=3D"color:rgb(0,128,0);font-size:small;background-color:rgb(255=
,255,254);text-decoration-style:initial;text-decoration-color:initial;float=
:none;display:inline"><br></span></font></div>// gcc uses the fs register t=
o address thread_local data. Zero overhead.</span><div style=3D"color:rgb(0=
,0,0);background-color:rgb(255,255,254)"><span style=3D"color:rgb(0,0,255)"=
>thread_local</span> second_stack_impl second_stack;<br></div></font><br></=
div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-0240-=
4130-8918-0b1dbe924452%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hZi1WzmWFHnQ5bO-uQ1UHG_ba6QHPz1=
DdFnrzQpJJH2zA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hZi1WzmWFHn=
Q5bO-uQ1UHG_ba6QHPz1DdFnrzQpJJH2zA%40mail.gmail.com</a>.<br />

--000000000000030ee70570cb2330--

.


Author: florian.csdt@gmail.com
Date: Thu, 12 Jul 2018 04:23:52 -0700 (PDT)
Raw View
------=_Part_135990_1583706691.1531394632995
Content-Type: multipart/alternative;
 boundary="----=_Part_135991_859476670.1531394632996"

------=_Part_135991_859476670.1531394632996
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le jeudi 12 juillet 2018 12:50:53 UTC+2, Richard Hodges a =C3=A9crit :
>
>
>
> On Thu, 12 Jul 2018 at 12:02, <floria...@gmail.com <javascript:>> wrote:
>
>>
>>
>> Le jeudi 12 juillet 2018 10:36:38 UTC+2, Richard Hodges a =C3=A9crit :
>>>
>>>
>>>
>>> On Thu, 12 Jul 2018 at 09:55, <floria...@gmail.com> wrote:
>>>
>>>>
>>>>
>>>> Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit :
>>>>>
>>>>>
>>>>>
>>>>> On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <ma...@lysator.liu.se>=
=20
>>>>> wrote:
>>>>>
>>>>>> On Wed, Jul 11, 2018 at 08:26:44AM -0700, floria...@gmail.com wrote:
>>>>>> >=20
>>>>>> >=20
>>>>>> > >
>>>>>> > > And if it could do that, why not just let the names be accessibl=
e=20
>>>>>> too? If=20
>>>>>> > > we're relying on the existence of some objects, then rely on it=
=20
>>>>>> already.=20
>>>>>> > > And if we're going that far, why not allow the `inline!` functio=
n=20
>>>>>> be able=20
>>>>>> > > to return *for* its caller rather than *to* its caller? Or affec=
t=20
>>>>>> its=20
>>>>>> > > caller in other ways.
>>>>>> > >
>>>>>> > > You can see that we're quickly moving away from being a mere=20
>>>>>> "function"=20
>>>>>> > > and becoming something else: a named series of statements that=
=20
>>>>>> get=20
>>>>>> > > copy-pasted into code. That might be a useful feature or a=20
>>>>>> confusing one.=20
>>>>>> > > But this half-state between them that you propose is exactly=20
>>>>>> that: a=20
>>>>>> > > half-state. Neither one thing nor the other, the construct is=20
>>>>>> only useful=20
>>>>>> > > in a trivial number of instances.
>>>>>> > >
>>>>>> >=20
>>>>>> >  @Nicol:
>>>>>> > Here, you're completely right: those are not really functions=20
>>>>>> anymore.
>>>>>> >=20
>>>>>> > However, I would avoid putting names in the caller scope: this mor=
e=20
>>>>>> > annoying than it is solving issues.
>>>>>> > Keeping temporaries because they are referenced elsewhere would be=
=20
>>>>>> the main=20
>>>>>> > goal.
>>>>>>
>>>>>> I would say it was a novel but peculiar way to introduce anonymous=
=20
>>>>>> variables.
>>>>>>
>>>>>> inline! std::string_view makeFoo()
>>>>>> {
>>>>>>   std::string mAnon(initialize());
>>>>>>   return mAnon;
>>>>>> }
>>>>>>
>>>>>> Thanks to the inline! the string_view is valid in the returned=20
>>>>>> context.=20
>>>>>
>>>>>
>>>>> This is adding a cryptic language feature in order to carry a=20
>>>>> dependency through a reference in a hidden way. It is the exact oppos=
ite of=20
>>>>> all the good things that have happened to c++ since 2011. Value seman=
tics,=20
>>>>> good. Tidying up after dangling references, bad.
>>>>>
>>>>> Questions:
>>>>>
>>>>> a) how would you express this bizzareness in the standard?
>>>>>
>>>>
>>>> Simple, I already did.
>>>> The callee scope is the same as the caller scope. perdiod.
>>>> All the bizareness are handled by this simple rule.
>>>> We could enforce more: like the definition must be visible, inline!=20
>>>> recursion is not allowed, taking a pointer to such a functions is not=
=20
>>>> allowed...
>>>>
>>>>
>>>>> b) how would you teach it?
>>>>>
>>>>
>>>> How do you teach macros?
>>>> =20
>>>>
>>>>>
>>>>> c) why do you want to return a string_view here (a.k.a. dangling=20
>>>>> references mk 2) when you could simply return the string?
>>>>>
>>>>
>>>> If you need to chain functions, it can become clearer returning=20
>>>> directly the non-owning wrapper, especially if the conversion between =
the=20
>>>> actual object and the non owning wrapper is not automatic (std::md_spa=
n?).
>>>> But I have to say, it's a small motivation.
>>>> =20
>>>>
>>>>>
>>>>> I'm still waiting for someone to post a real motivating use case. So=
=20
>>>>> far none have been forthcoming. Frankly this is unsurprising. Some fe=
ature=20
>>>>> ideas are simply not destined to survive birth.
>>>>> =20
>>>>>
>>>>
>>>> I already post a valid use case I needed quite a lot: "returning"=20
>>>> runtime sized objects.
>>>> Even if you had VLAs, it would still not be possible to return them,=
=20
>>>> only a view on it. So the only way to have this working is the allocat=
ed=20
>>>> space must outlive the callee.
>>>> And alloca might not be part of the C++ standard, it is part of POSIX,=
=20
>>>> hence is supported by most platforms (it is also supported on windows)=
..
>>>> So it is possible (and easy) to write portable code using alloca. But=
=20
>>>> as you cannot really return the allocated space from alloca, you need =
to=20
>>>> either do heap allocations (slow), or rely on macros (bad).
>>>> And this inline! would be a big step forward to use such mechanism.
>>>>
>>>> You could argue it would be better to standardize runtime sized=20
>>>> objects, and I would agree. But the cost of standardizing such objects=
 is=20
>>>> extremely high, especially if you allow to return such objects.
>>>> My proposal is the opposite: it is simple to standardize/implement,=20
>>>> while still being useful.
>>>>
>>>> You did not even try to say why it is bad. You just said it is somehow=
=20
>>>> possible now (except the part with alloca, which is my main use case f=
or=20
>>>> that), but it requires more lines, is more cryptic to read...
>>>>
>>>> I don't say what I propose should defenitely go into the standard. It=
=20
>>>> is not perfect and I know it. But I answered clearly to all your=20
>>>> objections, and you don't really have valid arguments against it.
>>>> So please take time to consider everything I said before writing a=20
>>>> reply, otherwise your might repeat objections I already answered witho=
ut=20
>>>> any added value.
>>>>
>>>> Also, don't forget the start point: a way to have forced inlining in=
=20
>>>> the laguage using the terms of the language itself.
>>>> You might disagree that it is useful to standardize forced inlining,=
=20
>>>> and you might be right in theory.
>>>> In practice, this feature is used in so many codebases that it might b=
e=20
>>>> worth standardizing.
>>>> And what I propose is a simple way to do it. I think it is even simple=
r=20
>>>> like that than an attribute (because we cannot talk properly about inl=
ining=20
>>>> within the standard).
>>>>
>>>
>>> The inline keyword has changed meaning over the lifetime of c++. Once=
=20
>>> upon a time it means "please inline this unless it's a daft idea". Over=
=20
>>> time it became apparent that was not required or desirable. inline chan=
ged=20
>>> meaning to mean (in reality) "let me define this in a header file". Sti=
ll=20
>>> not a great keyword as it still doesn't imbue *semantic meaning*. It=20
>>> merely dances around a common implementation details of compilers.=20
>>> __forceinline was a compiler-specific optimisation which was introduced=
 to=20
>>> overcome history deficiencies in optimisers - as a community we were st=
ill=20
>>> learning. We (I) used to use asm("") a lot too. Not so much these days.=
=20
>>>
>>
>> The old meaning of inline was inherited from C. So it does not really=20
>> apply to C++ as the specification is different, and rely on an abstract=
=20
>> machine. But that's not really relevant to the discussion anyway.
>> The meaning has evolved because we needed a way to express the new idea,=
=20
>> and inline was close enough, so was simpler to repurpose this keyword=20
>> instead of creating a new one. This has nothing to do with implementatio=
n.
>>
>> Forced inlining is still used a lot, and in majority for good reasons:=
=20
>> optimizing compilers are not almighty and never will. We will always nee=
d=20
>> force inline and asm. Less and less, I agree, but still.
>>
>>
>>> If anything, inline should probably be a pragma or an [[attribute]]=20
>>> rather than a keyword. But history is history.
>>>
>>
>> Not with the current meaning. Actually, I think all functions should be=
=20
>> "inline" and the keyword deprecated. Most already are by default (templa=
tes=20
>> and in-class defined methods).
>> =20
>>
>>>
>>> Returning the result of alloca, and extending the caller's stack frame=
=20
>>> in magical ways is very much in the realm of implementation details, no=
t *semantic=20
>>> meaning*.
>>>
>>
>> It is an implementation detail to do something that is not currently=20
>> possible to do efficiently, ie: returning a runtime sized object. The on=
ly=20
>> way to do it currently is with heap allocation, no matter what.
>> =20
>>
>>>
>>> Frankly though, if we're going to use alloca (stack storage being used=
=20
>>> for something it should not be used for), why not use an alloca-heap an=
d=20
>>> provide a mechanism to deliver objects from it?
>>>
>>
>> Because if you want the speed of alloca, you want the speed of alloca,=
=20
>> not something slower. What you propose will be slower (faster than regul=
ar=20
>> heap allocation, though).
>> =20
>>
>>>
>>> We already have all the machinery for this. The thing you return can be=
=20
>>> implemented in terms of a std::unique_ptr with custom deleter. The=20
>>> alloca-heap can be thread_local if required to eliminate fence-induced=
=20
>>> delays.
>>>
>>
>> Not as efficient as alloca is. You cannot beat alloca.
>> =20
>>
>>>
>>> But then again, why? If we really want such fine-grained control over=
=20
>>> lifetimes of variables used by a function, simply pass the function a=
=20
>>> context object that contains (perhaps opaquely) the variables. Or imple=
ment=20
>>> the function as a member of the context object.=20
>>>
>>> We can already achieve the optimisations you want while expressing=20
>>> semantic intent.
>>>
>>> eg:
>>>
>>> for(auto fooContext =3D Foo() ; maybe() ; )
>>> {
>>>   auto& bar =3D fooContext.barPrep();
>>>   makeUseOf(bar);
>>> }
>>>
>>
>> But this cannot work with runtime sized objects. If you have a proposal=
=20
>> for runtime sized object that allows to return such objects that is almo=
st=20
>> ready, then fine. All my remarks don't apply anymore. But that's not the=
=20
>> case.
>> And standardizing runtime sized objects, while completely worthwile, wil=
l=20
>> be a very long and hard task.
>> What I propose is a simple workaround that will be able to handle a bunc=
h=20
>> of useful cases.
>>
>> Also, if you don't need to be as fast as what I'm looking for, then fine=
,=20
>> you don't need that, but I still do, and I'm not the only one.
>> =20
>>
>>> =20
>>> AFAIR the intent was to lengthen the lifetime of storage used in barPre=
p=20
>>> - that's done. Foo can be implemented in whatever "optimising" way the=
=20
>>> developer wishes. Using existing language features.
>>>
>>
>> As long as you don't need runtime sized objects, yes.
>> Runtime sized objects will be a deal breaker, especially for HPC. This=
=20
>> would avoid the need to preallocate enough memory beforehand and pass th=
ose=20
>> to every single function that needs it, and without relying only TLS.
>> But currently, it is not possible to have this, and it will come at grea=
t=20
>> standardizing costs.
>>
>
> I've worked with HPC and grid computing in computation of value and risk=
=20
> in exotic derivatives. I am unimpressed with performance-based arguments=
=20
> for standardising hacks.
>

It's not about hacks, it's about runtime sized objects. If you consider=20
runtime sized objects a hack then I have nothing more to say.

Also please remember the starting point: force inlining. The is, I believe,=
=20
the simplest way to standardize forced inlining. I also showed that it=20
could enable extra features that are not efficiently possible now.
=20

>
> If it's really necessary (and it almost never is), we can easily build=20
> safe alloca-like behaviour with a second-stack custom allocator,=20
> implemented in terms of a thread_local second_stack_impl:
>

If you use TLS within a loop, you have already lost.
Moreover, what if you need to allocate more heap because it was not big=20
enough? Do you want to pay this reallocation? Do you want to pay the branch=
=20
required to handle it?

There is a solution to that, and it already works on every single compiler:=
=20
alloca + forced inlining. What do you want to recreate something emulating=
=20
that which will be both slower and larger code?
=20

>
> struct second_stack_impl
> {
>   static constexpr std::size_t rounding =3D sizeof(std::uintptr_t); // et=
c
>   static constexpr std::size_t size =3D 1024 * 1024; // or by runtime con=
fig
>
>   std::byte* alloc(std::size_t bytes)
>   {
>     // round and allocate from second stack,
>     // store size
>     // return address of allocated data
>   }
>
>   void dealloc()
>   {
>     // recover size from stack top and=20
>     // return to stack
>   }
>
>   std::array<std::byte, size> storage;
>   std::byte* top =3D storage.data() + size;
> };
>
> // gcc uses the fs register to address thread_local data. Zero overhead.
> thread_local second_stack_impl second_stack;
>
>
Oups, your max size was not enough...
Also, TLS has always an overhead. It's close to zero when compiling=20
statically, but not everybody compile statically. And even in that case,=20
your solution will be slower than just using alloca.
=20

>
> =20
>
>> --=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit=20
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-02=
40-4130-8918-0b1dbe924452%40isocpp.org=20
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-0=
240-4130-8918-0b1dbe924452%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoo=
ter>
>> .
>>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1ca6a29e-8e5c-4cce-8b8f-61435c76d124%40isocpp.or=
g.

------=_Part_135991_859476670.1531394632996
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 12:50:53 UTC+2, Richard H=
odges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 =
Jul 2018 at 12:02, &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"LDeUHRH9CAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">floria...@gmail.com</a>&gt; wrote:<br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 10:36:3=
8 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr=
">On Thu, 12 Jul 2018 at 09:55, &lt;<a rel=3D"nofollow">floria...@gmail.com=
</a>&gt; wrote:<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"><b=
r><br>Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br><di=
v class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 Jul 2018 at 03:34, Magn=
us Fromreide &lt;<a rel=3D"nofollow">ma...@lysator.liu.se</a>&gt; wrote:<br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex">On Wed, Jul 11, 2018 at 08:26:44AM -0=
700, <a rel=3D"nofollow">floria...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div></div></div></blockquote><d=
iv><br></div><div>Simple, I already did.</div><div>The callee scope is the =
same as the caller scope. perdiod.</div><div>All the bizareness are handled=
 by this simple rule.</div><div>We could enforce more: like the definition =
must be visible, inline! recursion is not allowed, taking a pointer to such=
 a functions is not allowed...<br></div><div> <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br=
></div><div>b) how would you teach it?</div></div></div></blockquote><div><=
br></div><div>How do you teach macros?<br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><=
div><br></div><div>c) why do you want to return a string_view here (a.k.a. =
dangling references mk 2) when you could simply return the string?</div></d=
iv></div></blockquote><div><br></div><div>If you need to chain functions, i=
t can become clearer returning directly the non-owning wrapper, especially =
if the conversion between the actual object and the non owning wrapper is n=
ot automatic (std::md_span?).</div><div>But I have to say, it&#39;s a small=
 motivation.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>I&#39;m=
 still waiting for someone to post a real motivating use case. So far none =
have been forthcoming. Frankly this is unsurprising. Some feature ideas are=
 simply not destined to survive birth.</div><div>=C2=A0</div></div></div></=
blockquote><div><br></div><div>I already post a valid use case I needed qui=
te a lot: &quot;returning&quot; runtime sized objects.</div><div>Even if yo=
u had VLAs, it would still not be possible to return them, only a view on i=
t. So the only way to have this working is the allocated space must outlive=
 the callee.</div><div>And alloca might not be part of the C++ standard, it=
 is part of POSIX, hence is supported by most platforms (it is also support=
ed on windows).</div><div>So it is possible (and easy) to write portable co=
de using alloca. But as you cannot really return the allocated space from a=
lloca, you need to either do heap allocations (slow), or rely on macros (ba=
d).</div><div>And this inline! would be a big step forward to use such mech=
anism.</div><div><br></div><div>You could argue it would be better to stand=
ardize runtime sized objects, and I would agree. But the cost of standardiz=
ing such objects is extremely high, especially if you allow to return such =
objects.</div><div>My proposal is the opposite: it is simple to standardize=
/implement, while still being useful.<br></div><div><br></div><div>You did =
not even try to say why it is bad. You just said it is somehow possible now=
 (except the part with alloca, which is my main use case for that), but it =
requires more lines, is more cryptic to read...</div><div><br></div><div>I =
don&#39;t say what I propose should defenitely go into the standard. It is =
not perfect and I know it. But I answered clearly to all your objections, a=
nd you don&#39;t really have valid arguments against it.</div><div>So pleas=
e take time to consider everything I said before writing a reply, otherwise=
 your might repeat objections I already answered without any added value.</=
div><div><br></div><div>Also, don&#39;t forget the start point: a way to ha=
ve forced inlining in the laguage using the terms of the language itself.</=
div><div>You might disagree that it is useful to standardize forced inlinin=
g, and you might be right in theory.</div><div>In practice, this feature is=
 used in so many codebases that it might be worth standardizing.</div><div>=
And what I propose is a simple way to do it. I think it is even simpler lik=
e that than an attribute (because we cannot talk properly about inlining wi=
thin the standard).<br></div></div></blockquote><div><br></div><div>The inl=
ine keyword has changed meaning over the lifetime of c++. Once upon a time =
it means &quot;please inline this unless it&#39;s a daft idea&quot;. Over t=
ime it became apparent that was not required or desirable. inline changed m=
eaning to mean (in reality) &quot;let me define this in a header file&quot;=
.. Still not a great keyword as it still doesn&#39;t imbue <i>semantic meani=
ng</i>. It merely dances around a common implementation details of compiler=
s. __forceinline was a compiler-specific optimisation which was introduced =
to overcome history deficiencies in optimisers - as a community we were sti=
ll learning. We (I) used to use asm(&quot;&quot;) a lot too. Not so much th=
ese days.=C2=A0</div></div></div></blockquote><div><br></div><div>The old m=
eaning of inline was inherited from C. So it does not really apply to C++ a=
s the specification is different, and rely on an abstract machine. But that=
&#39;s not really relevant to the discussion anyway.</div><div>The meaning =
has evolved because we needed a way to express the new idea, and inline was=
 close enough, so was simpler to repurpose this keyword instead of creating=
 a new one. This has nothing to do with implementation.</div><div><br></div=
><div>Forced inlining is still used a lot, and in majority for good reasons=
: optimizing compilers are not almighty and never will. We will always need=
 force inline and asm. Less and less, I agree, but still.<br></div><div> <b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_quote"><div><br></div><div>If anything, inline should probably be=
 a pragma or an [[attribute]] rather than a keyword. But history is history=
..</div></div></div></blockquote><div><br></div><div>Not with the current me=
aning. Actually, I think all functions should be &quot;inline&quot; and the=
 keyword deprecated. Most already are by default (templates and in-class de=
fined methods).<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>Retu=
rning the result of alloca, and extending the caller&#39;s stack frame in m=
agical ways is very much in the realm of implementation details, not <i>sem=
antic meaning</i>.</div></div></div></blockquote><div><br></div><div>It is =
an implementation detail to do something that is not currently possible to =
do efficiently, ie: returning a runtime sized object. The only way to do it=
 currently is with heap allocation, no matter what.<br></div><div>=C2=A0</d=
iv><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 class=3D"g=
mail_quote"><div><br></div><div>Frankly though, if we&#39;re going to use a=
lloca (stack storage being used for something it should not be used for), w=
hy not use an alloca-heap and provide a mechanism to deliver objects from i=
t?</div></div></div></blockquote><div><br></div><div>Because if you want th=
e speed of alloca, you want the speed of alloca, not something slower. What=
 you propose will be slower (faster than regular heap allocation, though).<=
br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>We already have all=
 the machinery for this. The thing you return can be implemented in terms o=
f a std::unique_ptr with custom deleter. The alloca-heap can be thread_loca=
l if required to eliminate fence-induced delays.</div></div></div></blockqu=
ote><div><br></div><div>Not as efficient as alloca is. You cannot beat allo=
ca.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>But then again, =
why? If we really want such fine-grained control over lifetimes of variable=
s used by a function, simply pass the function a context object that contai=
ns (perhaps opaquely) the variables. Or implement the function as a member =
of the context object.=C2=A0</div><div><br></div><div>We can already achiev=
e the optimisations you want while expressing semantic intent.</div><div><b=
r></div><div>eg:</div><div><br></div><div><span style=3D"font-family:monosp=
ace,monospace">for(</span><span style=3D"font-family:monospace,monospace">a=
uto fooContext =3D Foo() ;=C2=A0</span><span style=3D"font-family:monospace=
,monospace">maybe() ; )</span><br></div><div><font face=3D"monospace, monos=
pace">{</font></div><div><font face=3D"monospace, monospace">=C2=A0 auto&am=
p; bar =3D fooContext.barPrep();</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 makeUseOf(bar);</font></div><div><font face=3D"monospace,=
 monospace">}</font></div></div></div></blockquote><div><br></div><div>But =
this cannot work with runtime sized objects. If you have a proposal for run=
time sized object that allows to return such objects that is almost ready, =
then fine. All my remarks don&#39;t apply anymore. But that&#39;s not the c=
ase.</div><div>And standardizing runtime sized objects, while completely wo=
rthwile, will be a very long and hard task.</div><div>What I propose is a s=
imple workaround that will be able to handle a bunch of useful cases.</div>=
<div><br></div><div>Also, if you don&#39;t need to be as fast as what I&#39=
;m looking for, then fine, you don&#39;t need that, but I still do, and I&#=
39;m not the only one.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div>=C2=A0</div>=
<div>AFAIR the intent was to lengthen the lifetime of storage used in barPr=
ep - that&#39;s done. Foo can be implemented in whatever &quot;optimising&q=
uot; way the developer wishes. Using existing language features.</div></div=
></div></blockquote><div><br></div><div>As long as you don&#39;t need runti=
me sized objects, yes.</div><div>Runtime sized objects will be a deal break=
er, especially for HPC. This would avoid the need to preallocate enough mem=
ory beforehand and pass those to every single function that needs it, and w=
ithout relying only TLS.</div><div>But currently, it is not possible to hav=
e this, and it will come at great standardizing costs.<br></div></div></blo=
ckquote><div><br></div><div>I&#39;ve worked with HPC and grid computing in =
computation of value and risk in exotic derivatives. I am unimpressed with =
performance-based arguments for standardising hacks.</div></div></div></blo=
ckquote><div><br></div><div>It&#39;s not about hacks, it&#39;s about runtim=
e sized objects. If you consider runtime sized objects a hack then I have n=
othing more to say.</div><div><br></div><div>Also please remember the start=
ing point: force inlining. The is, I believe, the simplest way to standardi=
ze forced inlining. I also showed that it could enable extra features that =
are not efficiently possible now.<br></div><div>=C2=A0</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><=
div><br></div><div>If it&#39;s really necessary (and it almost never is), w=
e can easily build safe alloca-like behaviour with a second-stack custom al=
locator, implemented in terms of a thread_local second_stack_impl:</div></d=
iv></div></blockquote><div><br></div><div>If you use TLS within a loop, you=
 have already lost.</div><div>Moreover, what if you need to allocate more h=
eap because it was not big enough? Do you want to pay this reallocation? Do=
 you want to pay the branch required to handle it?</div><div><br></div><div=
>There is a solution to that, and it already works on every single compiler=
: alloca + forced inlining. What do you want to recreate something emulatin=
g that which will be both slower and larger code?<br></div><div>=C2=A0</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 class=
=3D"gmail_quote"><div><br></div><div><div style=3D"color:rgb(0,0,0);backgro=
und-color:rgb(255,255,254)"><div><font face=3D"monospace, monospace"><span =
style=3D"color:rgb(0,0,255)">struct</span><span style=3D"color:rgb(0,0,0)">=
 second_stack_impl</span></font></div><div><span style=3D"color:rgb(0,0,0)"=
><font face=3D"monospace, monospace">{</font></span></div><div><font face=
=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></span><span sty=
le=3D"color:rgb(0,0,255)">=C2=A0 static</span><span style=3D"color:rgb(0,0,=
0)"> </span><span style=3D"color:rgb(0,0,255)">constexpr</span><span style=
=3D"color:rgb(0,0,0)"> std::size_t rounding =3D </span><span style=3D"color=
:rgb(0,0,255)">sizeof</span><span style=3D"color:rgb(0,0,0)">(std::uintptr_=
t); // etc</span></font></div><div><font face=3D"monospace, monospace"><spa=
n style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255)">=C2=
=A0 static</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(0,0,255)">constexpr</span><span style=3D"color:rgb(0,0,0)"> std::si=
ze_t size =3D </span><span style=3D"color:rgb(9,136,90)">1024</span><span s=
tyle=3D"color:rgb(0,0,0)"> * </span><span style=3D"color:rgb(9,136,90)">102=
4</span><span style=3D"color:rgb(0,0,0)">; // or by runtime config</span></=
font></div><font face=3D"monospace, monospace"><br></font><div><span style=
=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 std::byte*=
 alloc(std::size_t bytes)</font></span></div><div><span style=3D"color:rgb(=
0,0,0)"><font face=3D"monospace, monospace">=C2=A0 {</font></span></div><di=
v><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></sp=
an><span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // round and allocate f=
rom second stack,</span></font></div><div><font face=3D"monospace, monospac=
e"><span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,128,0=
)">=C2=A0 =C2=A0 // store size</span></font></div><div><font face=3D"monosp=
ace, monospace"><span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // return =
address of allocated data</span></font></div><div><span style=3D"color:rgb(=
0,0,0)"><font face=3D"monospace, monospace">=C2=A0 }</font></span></div><fo=
nt face=3D"monospace, monospace"><br></font><div><font face=3D"monospace, m=
onospace"><span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(=
0,0,255)">=C2=A0 void</span><span style=3D"color:rgb(0,0,0)"> dealloc()</sp=
an></font></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospa=
ce, monospace">=C2=A0 {</font></span></div><div><font face=3D"monospace, mo=
nospace"><span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0=
,128,0)">=C2=A0 =C2=A0 // recover size from stack top and </span></font></d=
iv><div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)=
"></span><span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // return to stac=
k</span></font></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"mo=
nospace, monospace">=C2=A0 }</font></span></div><font face=3D"monospace, mo=
nospace"><br></font><div><span style=3D"color:rgb(0,0,0)"><font face=3D"mon=
ospace, monospace">=C2=A0 std::array&lt;std::byte, size&gt; storage;</font>=
</span></div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace,=
 monospace">=C2=A0 std::byte* top =3D storage.data() + size;</font></span><=
/div><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospa=
ce">};</font></span></div><font face=3D"monospace, monospace"><span style=
=3D"color:rgb(0,128,0);font-size:small;background-color:rgb(255,255,254);fl=
oat:none;display:inline"><div style=3D"color:rgb(0,0,0);background-color:rg=
b(255,255,254)"><font face=3D"monospace, monospace"><span style=3D"color:rg=
b(0,128,0);font-size:small;background-color:rgb(255,255,254);float:none;dis=
play:inline"><br></span></font></div>// gcc uses the fs register to address=
 thread_local data. Zero overhead.</span><div style=3D"color:rgb(0,0,0);bac=
kground-color:rgb(255,255,254)"><span style=3D"color:rgb(0,0,255)">thread_l=
ocal</span> second_stack_impl second_stack;<br></div></font><br></div></div=
></div></div></blockquote><div><br></div><div>Oups, your max size was not e=
nough...</div><div>Also, TLS has always an overhead. It&#39;s close to zero=
 when compiling statically, but not everybody compile statically. And even =
in that case, your solution will be slower than just using alloca.<br></div=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div class=3D"gmail_quote"><div><div style=3D"color:rgb(0,0,0);backgro=
und-color:rgb(255,255,254)"></div><br></div><div>=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
LDeUHRH9CAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">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"LDeUHRH9CAAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/393f701c-0240-4130-8918-0b1dbe924452%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/393f701c-0240-4130-<wbr>8918-=
0b1dbe924452%40isocpp.org</a><wbr>.<br>
</blockquote></div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1ca6a29e-8e5c-4cce-8b8f-61435c76d124%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1ca6a29e-8e5c-4cce-8b8f-61435c76d124=
%40isocpp.org</a>.<br />

------=_Part_135991_859476670.1531394632996--

------=_Part_135990_1583706691.1531394632995--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Thu, 12 Jul 2018 13:15:09 +0100
Raw View
--0000000000003747a30570cc5173
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Thu, 12 Jul 2018 at 12:23, <florian.csdt@gmail.com> wrote:

>
>
> Le jeudi 12 juillet 2018 12:50:53 UTC+2, Richard Hodges a =C3=A9crit :
>>
>>
>>
>> On Thu, 12 Jul 2018 at 12:02, <floria...@gmail.com> wrote:
>>
>>>
>>>
>>> Le jeudi 12 juillet 2018 10:36:38 UTC+2, Richard Hodges a =C3=A9crit :
>>>>
>>>>
>>>>
>>>> On Thu, 12 Jul 2018 at 09:55, <floria...@gmail.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Hodges a =C3=A9crit =
:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Thu, 12 Jul 2018 at 03:34, Magnus Fromreide <ma...@lysator.liu.se=
>
>>>>>> wrote:
>>>>>>
>>>>>>> On Wed, Jul 11, 2018 at 08:26:44AM -0700, floria...@gmail.com wrote=
:
>>>>>>> >
>>>>>>> >
>>>>>>> > >
>>>>>>> > > And if it could do that, why not just let the names be
>>>>>>> accessible too? If
>>>>>>> > > we're relying on the existence of some objects, then rely on it
>>>>>>> already.
>>>>>>> > > And if we're going that far, why not allow the `inline!`
>>>>>>> function be able
>>>>>>> > > to return *for* its caller rather than *to* its caller? Or
>>>>>>> affect its
>>>>>>> > > caller in other ways.
>>>>>>> > >
>>>>>>> > > You can see that we're quickly moving away from being a mere
>>>>>>> "function"
>>>>>>> > > and becoming something else: a named series of statements that
>>>>>>> get
>>>>>>> > > copy-pasted into code. That might be a useful feature or a
>>>>>>> confusing one.
>>>>>>> > > But this half-state between them that you propose is exactly
>>>>>>> that: a
>>>>>>> > > half-state. Neither one thing nor the other, the construct is
>>>>>>> only useful
>>>>>>> > > in a trivial number of instances.
>>>>>>> > >
>>>>>>> >
>>>>>>> >  @Nicol:
>>>>>>> > Here, you're completely right: those are not really functions
>>>>>>> anymore.
>>>>>>> >
>>>>>>> > However, I would avoid putting names in the caller scope: this
>>>>>>> more
>>>>>>> > annoying than it is solving issues.
>>>>>>> > Keeping temporaries because they are referenced elsewhere would b=
e
>>>>>>> the main
>>>>>>> > goal.
>>>>>>>
>>>>>>> I would say it was a novel but peculiar way to introduce anonymous
>>>>>>> variables.
>>>>>>>
>>>>>>> inline! std::string_view makeFoo()
>>>>>>> {
>>>>>>>   std::string mAnon(initialize());
>>>>>>>   return mAnon;
>>>>>>> }
>>>>>>>
>>>>>>> Thanks to the inline! the string_view is valid in the returned
>>>>>>> context.
>>>>>>
>>>>>>
>>>>>> This is adding a cryptic language feature in order to carry a
>>>>>> dependency through a reference in a hidden way. It is the exact oppo=
site of
>>>>>> all the good things that have happened to c++ since 2011. Value sema=
ntics,
>>>>>> good. Tidying up after dangling references, bad.
>>>>>>
>>>>>> Questions:
>>>>>>
>>>>>> a) how would you express this bizzareness in the standard?
>>>>>>
>>>>>
>>>>> Simple, I already did.
>>>>> The callee scope is the same as the caller scope. perdiod.
>>>>> All the bizareness are handled by this simple rule.
>>>>> We could enforce more: like the definition must be visible, inline!
>>>>> recursion is not allowed, taking a pointer to such a functions is not
>>>>> allowed...
>>>>>
>>>>>
>>>>>> b) how would you teach it?
>>>>>>
>>>>>
>>>>> How do you teach macros?
>>>>>
>>>>>
>>>>>>
>>>>>> c) why do you want to return a string_view here (a.k.a. dangling
>>>>>> references mk 2) when you could simply return the string?
>>>>>>
>>>>>
>>>>> If you need to chain functions, it can become clearer returning
>>>>> directly the non-owning wrapper, especially if the conversion between=
 the
>>>>> actual object and the non owning wrapper is not automatic (std::md_sp=
an?).
>>>>> But I have to say, it's a small motivation.
>>>>>
>>>>>
>>>>>>
>>>>>> I'm still waiting for someone to post a real motivating use case. So
>>>>>> far none have been forthcoming. Frankly this is unsurprising. Some f=
eature
>>>>>> ideas are simply not destined to survive birth.
>>>>>>
>>>>>>
>>>>>
>>>>> I already post a valid use case I needed quite a lot: "returning"
>>>>> runtime sized objects.
>>>>> Even if you had VLAs, it would still not be possible to return them,
>>>>> only a view on it. So the only way to have this working is the alloca=
ted
>>>>> space must outlive the callee.
>>>>> And alloca might not be part of the C++ standard, it is part of POSIX=
,
>>>>> hence is supported by most platforms (it is also supported on windows=
).
>>>>> So it is possible (and easy) to write portable code using alloca. But
>>>>> as you cannot really return the allocated space from alloca, you need=
 to
>>>>> either do heap allocations (slow), or rely on macros (bad).
>>>>> And this inline! would be a big step forward to use such mechanism.
>>>>>
>>>>> You could argue it would be better to standardize runtime sized
>>>>> objects, and I would agree. But the cost of standardizing such object=
s is
>>>>> extremely high, especially if you allow to return such objects.
>>>>> My proposal is the opposite: it is simple to standardize/implement,
>>>>> while still being useful.
>>>>>
>>>>> You did not even try to say why it is bad. You just said it is someho=
w
>>>>> possible now (except the part with alloca, which is my main use case =
for
>>>>> that), but it requires more lines, is more cryptic to read...
>>>>>
>>>>> I don't say what I propose should defenitely go into the standard. It
>>>>> is not perfect and I know it. But I answered clearly to all your
>>>>> objections, and you don't really have valid arguments against it.
>>>>> So please take time to consider everything I said before writing a
>>>>> reply, otherwise your might repeat objections I already answered with=
out
>>>>> any added value.
>>>>>
>>>>> Also, don't forget the start point: a way to have forced inlining in
>>>>> the laguage using the terms of the language itself.
>>>>> You might disagree that it is useful to standardize forced inlining,
>>>>> and you might be right in theory.
>>>>> In practice, this feature is used in so many codebases that it might
>>>>> be worth standardizing.
>>>>> And what I propose is a simple way to do it. I think it is even
>>>>> simpler like that than an attribute (because we cannot talk properly =
about
>>>>> inlining within the standard).
>>>>>
>>>>
>>>> The inline keyword has changed meaning over the lifetime of c++. Once
>>>> upon a time it means "please inline this unless it's a daft idea". Ove=
r
>>>> time it became apparent that was not required or desirable. inline cha=
nged
>>>> meaning to mean (in reality) "let me define this in a header file". St=
ill
>>>> not a great keyword as it still doesn't imbue *semantic meaning*. It
>>>> merely dances around a common implementation details of compilers.
>>>> __forceinline was a compiler-specific optimisation which was introduce=
d to
>>>> overcome history deficiencies in optimisers - as a community we were s=
till
>>>> learning. We (I) used to use asm("") a lot too. Not so much these days=
..
>>>>
>>>
>>> The old meaning of inline was inherited from C. So it does not really
>>> apply to C++ as the specification is different, and rely on an abstract
>>> machine. But that's not really relevant to the discussion anyway.
>>> The meaning has evolved because we needed a way to express the new idea=
,
>>> and inline was close enough, so was simpler to repurpose this keyword
>>> instead of creating a new one. This has nothing to do with implementati=
on.
>>>
>>> Forced inlining is still used a lot, and in majority for good reasons:
>>> optimizing compilers are not almighty and never will. We will always ne=
ed
>>> force inline and asm. Less and less, I agree, but still.
>>>
>>>
>>>> If anything, inline should probably be a pragma or an [[attribute]]
>>>> rather than a keyword. But history is history.
>>>>
>>>
>>> Not with the current meaning. Actually, I think all functions should be
>>> "inline" and the keyword deprecated. Most already are by default (templ=
ates
>>> and in-class defined methods).
>>>
>>>
>>>>
>>>> Returning the result of alloca, and extending the caller's stack frame
>>>> in magical ways is very much in the realm of implementation details, n=
ot *semantic
>>>> meaning*.
>>>>
>>>
>>> It is an implementation detail to do something that is not currently
>>> possible to do efficiently, ie: returning a runtime sized object. The o=
nly
>>> way to do it currently is with heap allocation, no matter what.
>>>
>>>
>>>>
>>>> Frankly though, if we're going to use alloca (stack storage being used
>>>> for something it should not be used for), why not use an alloca-heap a=
nd
>>>> provide a mechanism to deliver objects from it?
>>>>
>>>
>>> Because if you want the speed of alloca, you want the speed of alloca,
>>> not something slower. What you propose will be slower (faster than regu=
lar
>>> heap allocation, though).
>>>
>>>
>>>>
>>>> We already have all the machinery for this. The thing you return can b=
e
>>>> implemented in terms of a std::unique_ptr with custom deleter. The
>>>> alloca-heap can be thread_local if required to eliminate fence-induced
>>>> delays.
>>>>
>>>
>>> Not as efficient as alloca is. You cannot beat alloca.
>>>
>>>
>>>>
>>>> But then again, why? If we really want such fine-grained control over
>>>> lifetimes of variables used by a function, simply pass the function a
>>>> context object that contains (perhaps opaquely) the variables. Or impl=
ement
>>>> the function as a member of the context object.
>>>>
>>>> We can already achieve the optimisations you want while expressing
>>>> semantic intent.
>>>>
>>>> eg:
>>>>
>>>> for(auto fooContext =3D Foo() ; maybe() ; )
>>>> {
>>>>   auto& bar =3D fooContext.barPrep();
>>>>   makeUseOf(bar);
>>>> }
>>>>
>>>
>>> But this cannot work with runtime sized objects. If you have a proposal
>>> for runtime sized object that allows to return such objects that is alm=
ost
>>> ready, then fine. All my remarks don't apply anymore. But that's not th=
e
>>> case.
>>> And standardizing runtime sized objects, while completely worthwile,
>>> will be a very long and hard task.
>>> What I propose is a simple workaround that will be able to handle a
>>> bunch of useful cases.
>>>
>>> Also, if you don't need to be as fast as what I'm looking for, then
>>> fine, you don't need that, but I still do, and I'm not the only one.
>>>
>>>
>>>>
>>>> AFAIR the intent was to lengthen the lifetime of storage used in
>>>> barPrep - that's done. Foo can be implemented in whatever "optimising"=
 way
>>>> the developer wishes. Using existing language features.
>>>>
>>>
>>> As long as you don't need runtime sized objects, yes.
>>> Runtime sized objects will be a deal breaker, especially for HPC. This
>>> would avoid the need to preallocate enough memory beforehand and pass t=
hose
>>> to every single function that needs it, and without relying only TLS.
>>> But currently, it is not possible to have this, and it will come at
>>> great standardizing costs.
>>>
>>
>> I've worked with HPC and grid computing in computation of value and risk
>> in exotic derivatives. I am unimpressed with performance-based arguments
>> for standardising hacks.
>>
>
> It's not about hacks, it's about runtime sized objects. If you consider
> runtime sized objects a hack then I have nothing more to say.
>

I have no problem talking about a way to standardise runtime-sized objects.
I do feel that starting with inline(true) and then turning that into a
discussion about runtime-sized objects is an XY discussion.


>
> Also please remember the starting point: force inlining. The is, I
> believe, the simplest way to standardize forced inlining. I also showed
> that it could enable extra features that are not efficiently possible now=
..
>

I don't believe you have demonstrated a direct use case that cannot be
achieved by another means. I think we owe it to ourselves to explore those
other means before changing the language.

>
>
>>
>> If it's really necessary (and it almost never is), we can easily build
>> safe alloca-like behaviour with a second-stack custom allocator,
>> implemented in terms of a thread_local second_stack_impl:
>>
>
> If you use TLS within a loop, you have already lost.
>

Not from the code I see produced by gcc. The FS register is used as the
base of statically allocated thread-local storage. At worst, thread-local
dynamic storage will required one pointer de-reference, which will be
subject to optimisation if done more than once.


> Moreover, what if you need to allocate more heap because it was not big
> enough? Do you want to pay this reallocation? Do you want to pay the bran=
ch
> required to handle it?
>

> There is a solution to that, and it already works on every single
> compiler: alloca + forced inlining. What do you want to recreate somethin=
g
> emulating that which will be both slower and larger code?
>

alloca uses the stack. If you run out of stack, get a segfault if you're
lucky. The comments in the code below mention that a second-stack can be of
configurable size. It could also be auto-growing with a little work.


>
>

>
>>
>> struct second_stack_impl
>> {
>>   static constexpr std::size_t rounding =3D sizeof(std::uintptr_t); // e=
tc
>>   static constexpr std::size_t size =3D 1024 * 1024; // or by runtime
>> config
>>
>>   std::byte* alloc(std::size_t bytes)
>>   {
>>     // round and allocate from second stack,
>>     // store size
>>     // return address of allocated data
>>   }
>>
>>   void dealloc()
>>   {
>>     // recover size from stack top and
>>     // return to stack
>>   }
>>
>>   std::array<std::byte, size> storage;
>>   std::byte* top =3D storage.data() + size;
>> };
>>
>> // gcc uses the fs register to address thread_local data. Zero overhead.
>> thread_local second_stack_impl second_stack;
>>
>>
> Oups, your max size was not enough...
>

noted above.


> Also, TLS has always an overhead. It's close to zero when compiling
> statically, but not everybody compile statically. And even in that case,
> your solution will be slower than just using alloca.
>

inside out functions that expose alloca()-allocated objects require static
compilation at the very least. TLS has no overhead on gcc. Furthermore,
with the as-if and strict-aliasing rules, even if it did, it would be
minimal. c++ is defined in terms of an abstract object model, not a strict
act-on-memory model.

In addition, what happens if there are more than one alloca-allocated and
life-extended objects? How do we track destruction order? We have to,
otherwise interrupts and intermediate stack use will clobber our objects.
There is no realloc equivalent with alloca. You don't want to be using it
in a loop, ever.

Please note that alloca() is *not* part of the posix standard. It's a GNU
extension.

I agree that pre-allocating storage can be a useful optimisation.
I am fine with that storage being on the stack.
I agree that it's nice to hide that detail behind an abstraction.
I think we already have a number of ways to do it.
I'm happy to explore the pros and cons with you.
I don't think "inline!" looks like the right way.
I don't think it's useful to enter discussions on whether optimisation A is
better than optimisation B without some means of measurement.

I think we share a lot of common ground.


>
>
>>
>>
>>
>>> --
>>> 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.
>>> To view this discussion on the web visit
>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-0=
240-4130-8918-0b1dbe924452%40isocpp.org
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/393f701c-=
0240-4130-8918-0b1dbe924452%40isocpp.org?utm_medium=3Demail&utm_source=3Dfo=
oter>
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1ca6a29e-8e5=
c-4cce-8b8f-61435c76d124%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1ca6a29e-8e=
5c-4cce-8b8f-61435c76d124%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CALvx3hYwax0GwPaQk_9MP0tf3pNYojKuoi%2BdR-gBiieVP=
ga%2Baw%40mail.gmail.com.

--0000000000003747a30570cc5173
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu=
, 12 Jul 2018 at 12:23, &lt;<a href=3D"mailto:florian.csdt@gmail.com">flori=
an.csdt@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>Le jeudi 12 juillet 2018 12:50:53 UTC+2, Richard Hod=
ges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 Jul 201=
8 at 12:02, &lt;<a rel=3D"nofollow">floria...@gmail.com</a>&gt; wrote:<br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le jeudi 12 ju=
illet 2018 10:36:38 UTC+2, Richard Hodges a =C3=A9crit=C2=A0:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quot=
e"><div dir=3D"ltr">On Thu, 12 Jul 2018 at 09:55, &lt;<a rel=3D"nofollow">f=
loria...@gmail.com</a>&gt; wrote:<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"><br><br>Le jeudi 12 juillet 2018 09:05:51 UTC+2, Richard Ho=
dges a =C3=A9crit=C2=A0:<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"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 12 Jul 20=
18 at 03:34, Magnus Fromreide &lt;<a rel=3D"nofollow">ma...@lysator.liu.se<=
/a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Jul 11, 2018=
 at 08:26:44AM -0700, <a rel=3D"nofollow">floria...@gmail.com</a> wrote:<br=
>
&gt; <br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; And if it could do that, why not just let the names be accessible=
 too? If <br>
&gt; &gt; we&#39;re relying on the existence of some objects, then rely on =
it already. <br>
&gt; &gt; And if we&#39;re going that far, why not allow the `inline!` func=
tion be able <br>
&gt; &gt; to return *for* its caller rather than *to* its caller? Or affect=
 its <br>
&gt; &gt; caller in other ways.<br>
&gt; &gt;<br>
&gt; &gt; You can see that we&#39;re quickly moving away from being a mere =
&quot;function&quot; <br>
&gt; &gt; and becoming something else: a named series of statements that ge=
t <br>
&gt; &gt; copy-pasted into code. That might be a useful feature or a confus=
ing one. <br>
&gt; &gt; But this half-state between them that you propose is exactly that=
: a <br>
&gt; &gt; half-state. Neither one thing nor the other, the construct is onl=
y useful <br>
&gt; &gt; in a trivial number of instances.<br>
&gt; &gt;<br>
&gt; <br>
&gt;=C2=A0 @Nicol:<br>
&gt; Here, you&#39;re completely right: those are not really functions anym=
ore.<br>
&gt; <br>
&gt; However, I would avoid putting names in the caller scope: this more <b=
r>
&gt; annoying than it is solving issues.<br>
&gt; Keeping temporaries because they are referenced elsewhere would be the=
 main <br>
&gt; goal.<br>
<br>
I would say it was a novel but peculiar way to introduce anonymous variable=
s.<br>
<br>
inline! std::string_view makeFoo()<br>
{<br>
=C2=A0 std::string mAnon(initialize());<br>
=C2=A0 return mAnon;<br>
}<br>
<br>
Thanks to the inline! the string_view is valid in the returned context.=C2=
=A0</blockquote><div><br></div><div>This is adding a cryptic language featu=
re in order to carry a dependency through a reference in a hidden way. It i=
s the exact opposite of all the good things that have happened to c++ since=
 2011. Value semantics, good. Tidying up after dangling references, bad.</d=
iv><div><br></div><div>Questions:</div><div><br></div><div>a) how would you=
 express this bizzareness in the standard?</div></div></div></blockquote><d=
iv><br></div><div>Simple, I already did.</div><div>The callee scope is the =
same as the caller scope. perdiod.</div><div>All the bizareness are handled=
 by this simple rule.</div><div>We could enforce more: like the definition =
must be visible, inline! recursion is not allowed, taking a pointer to such=
 a functions is not allowed...<br></div><div> <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br=
></div><div>b) how would you teach it?</div></div></div></blockquote><div><=
br></div><div>How do you teach macros?<br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><=
div><br></div><div>c) why do you want to return a string_view here (a.k.a. =
dangling references mk 2) when you could simply return the string?</div></d=
iv></div></blockquote><div><br></div><div>If you need to chain functions, i=
t can become clearer returning directly the non-owning wrapper, especially =
if the conversion between the actual object and the non owning wrapper is n=
ot automatic (std::md_span?).</div><div>But I have to say, it&#39;s a small=
 motivation.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>I&#39;m=
 still waiting for someone to post a real motivating use case. So far none =
have been forthcoming. Frankly this is unsurprising. Some feature ideas are=
 simply not destined to survive birth.</div><div>=C2=A0</div></div></div></=
blockquote><div><br></div><div>I already post a valid use case I needed qui=
te a lot: &quot;returning&quot; runtime sized objects.</div><div>Even if yo=
u had VLAs, it would still not be possible to return them, only a view on i=
t. So the only way to have this working is the allocated space must outlive=
 the callee.</div><div>And alloca might not be part of the C++ standard, it=
 is part of POSIX, hence is supported by most platforms (it is also support=
ed on windows).</div><div>So it is possible (and easy) to write portable co=
de using alloca. But as you cannot really return the allocated space from a=
lloca, you need to either do heap allocations (slow), or rely on macros (ba=
d).</div><div>And this inline! would be a big step forward to use such mech=
anism.</div><div><br></div><div>You could argue it would be better to stand=
ardize runtime sized objects, and I would agree. But the cost of standardiz=
ing such objects is extremely high, especially if you allow to return such =
objects.</div><div>My proposal is the opposite: it is simple to standardize=
/implement, while still being useful.<br></div><div><br></div><div>You did =
not even try to say why it is bad. You just said it is somehow possible now=
 (except the part with alloca, which is my main use case for that), but it =
requires more lines, is more cryptic to read...</div><div><br></div><div>I =
don&#39;t say what I propose should defenitely go into the standard. It is =
not perfect and I know it. But I answered clearly to all your objections, a=
nd you don&#39;t really have valid arguments against it.</div><div>So pleas=
e take time to consider everything I said before writing a reply, otherwise=
 your might repeat objections I already answered without any added value.</=
div><div><br></div><div>Also, don&#39;t forget the start point: a way to ha=
ve forced inlining in the laguage using the terms of the language itself.</=
div><div>You might disagree that it is useful to standardize forced inlinin=
g, and you might be right in theory.</div><div>In practice, this feature is=
 used in so many codebases that it might be worth standardizing.</div><div>=
And what I propose is a simple way to do it. I think it is even simpler lik=
e that than an attribute (because we cannot talk properly about inlining wi=
thin the standard).<br></div></div></blockquote><div><br></div><div>The inl=
ine keyword has changed meaning over the lifetime of c++. Once upon a time =
it means &quot;please inline this unless it&#39;s a daft idea&quot;. Over t=
ime it became apparent that was not required or desirable. inline changed m=
eaning to mean (in reality) &quot;let me define this in a header file&quot;=
.. Still not a great keyword as it still doesn&#39;t imbue <i>semantic meani=
ng</i>. It merely dances around a common implementation details of compiler=
s. __forceinline was a compiler-specific optimisation which was introduced =
to overcome history deficiencies in optimisers - as a community we were sti=
ll learning. We (I) used to use asm(&quot;&quot;) a lot too. Not so much th=
ese days.=C2=A0</div></div></div></blockquote><div><br></div><div>The old m=
eaning of inline was inherited from C. So it does not really apply to C++ a=
s the specification is different, and rely on an abstract machine. But that=
&#39;s not really relevant to the discussion anyway.</div><div>The meaning =
has evolved because we needed a way to express the new idea, and inline was=
 close enough, so was simpler to repurpose this keyword instead of creating=
 a new one. This has nothing to do with implementation.</div><div><br></div=
><div>Forced inlining is still used a lot, and in majority for good reasons=
: optimizing compilers are not almighty and never will. We will always need=
 force inline and asm. Less and less, I agree, but still.<br></div><div> <b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_quote"><div><br></div><div>If anything, inline should probably be=
 a pragma or an [[attribute]] rather than a keyword. But history is history=
..</div></div></div></blockquote><div><br></div><div>Not with the current me=
aning. Actually, I think all functions should be &quot;inline&quot; and the=
 keyword deprecated. Most already are by default (templates and in-class de=
fined methods).<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>Retu=
rning the result of alloca, and extending the caller&#39;s stack frame in m=
agical ways is very much in the realm of implementation details, not <i>sem=
antic meaning</i>.</div></div></div></blockquote><div><br></div><div>It is =
an implementation detail to do something that is not currently possible to =
do efficiently, ie: returning a runtime sized object. The only way to do it=
 currently is with heap allocation, no matter what.<br></div><div>=C2=A0</d=
iv><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 class=3D"g=
mail_quote"><div><br></div><div>Frankly though, if we&#39;re going to use a=
lloca (stack storage being used for something it should not be used for), w=
hy not use an alloca-heap and provide a mechanism to deliver objects from i=
t?</div></div></div></blockquote><div><br></div><div>Because if you want th=
e speed of alloca, you want the speed of alloca, not something slower. What=
 you propose will be slower (faster than regular heap allocation, though).<=
br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>We already have all=
 the machinery for this. The thing you return can be implemented in terms o=
f a std::unique_ptr with custom deleter. The alloca-heap can be thread_loca=
l if required to eliminate fence-induced delays.</div></div></div></blockqu=
ote><div><br></div><div>Not as efficient as alloca is. You cannot beat allo=
ca.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>But then again, =
why? If we really want such fine-grained control over lifetimes of variable=
s used by a function, simply pass the function a context object that contai=
ns (perhaps opaquely) the variables. Or implement the function as a member =
of the context object.=C2=A0</div><div><br></div><div>We can already achiev=
e the optimisations you want while expressing semantic intent.</div><div><b=
r></div><div>eg:</div><div><br></div><div><span style=3D"font-family:monosp=
ace,monospace">for(</span><span style=3D"font-family:monospace,monospace">a=
uto fooContext =3D Foo() ;=C2=A0</span><span style=3D"font-family:monospace=
,monospace">maybe() ; )</span><br></div><div><font face=3D"monospace, monos=
pace">{</font></div><div><font face=3D"monospace, monospace">=C2=A0 auto&am=
p; bar =3D fooContext.barPrep();</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 makeUseOf(bar);</font></div><div><font face=3D"monospace,=
 monospace">}</font></div></div></div></blockquote><div><br></div><div>But =
this cannot work with runtime sized objects. If you have a proposal for run=
time sized object that allows to return such objects that is almost ready, =
then fine. All my remarks don&#39;t apply anymore. But that&#39;s not the c=
ase.</div><div>And standardizing runtime sized objects, while completely wo=
rthwile, will be a very long and hard task.</div><div>What I propose is a s=
imple workaround that will be able to handle a bunch of useful cases.</div>=
<div><br></div><div>Also, if you don&#39;t need to be as fast as what I&#39=
;m looking for, then fine, you don&#39;t need that, but I still do, and I&#=
39;m not the only one.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div>=C2=A0</div>=
<div>AFAIR the intent was to lengthen the lifetime of storage used in barPr=
ep - that&#39;s done. Foo can be implemented in whatever &quot;optimising&q=
uot; way the developer wishes. Using existing language features.</div></div=
></div></blockquote><div><br></div><div>As long as you don&#39;t need runti=
me sized objects, yes.</div><div>Runtime sized objects will be a deal break=
er, especially for HPC. This would avoid the need to preallocate enough mem=
ory beforehand and pass those to every single function that needs it, and w=
ithout relying only TLS.</div><div>But currently, it is not possible to hav=
e this, and it will come at great standardizing costs.<br></div></div></blo=
ckquote><div><br></div><div>I&#39;ve worked with HPC and grid computing in =
computation of value and risk in exotic derivatives. I am unimpressed with =
performance-based arguments for standardising hacks.</div></div></div></blo=
ckquote><div><br></div><div>It&#39;s not about hacks, it&#39;s about runtim=
e sized objects. If you consider runtime sized objects a hack then I have n=
othing more to say.</div></div></blockquote><div><br></div><div>I have no p=
roblem talking about a way to standardise runtime-sized objects. I do feel =
that starting with inline(true) and then turning that into a discussion abo=
ut runtime-sized objects is an XY discussion.</div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>Also please re=
member the starting point: force inlining. The is, I believe, the simplest =
way to standardize forced inlining. I also showed that it could enable extr=
a features that are not efficiently possible now.<br></div></div></blockquo=
te><div><br></div><div>I don&#39;t believe you have demonstrated a direct u=
se case that cannot be achieved by another means. I think we owe it to ours=
elves to explore those other means before changing the language.=C2=A0</div=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gm=
ail_quote"><div><br></div><div>If it&#39;s really necessary (and it almost =
never is), we can easily build safe alloca-like behaviour with a second-sta=
ck custom allocator, implemented in terms of a thread_local second_stack_im=
pl:</div></div></div></blockquote><div><br></div><div>If you use TLS within=
 a loop, you have already lost.</div></div></blockquote><div><br></div><div=
>Not from the code I see produced by gcc. The FS register is used as the ba=
se of statically allocated thread-local storage. At worst, thread-local dyn=
amic storage will required one pointer de-reference, which will be subject =
to optimisation if done more than once.</div><div>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>Moreover, what if you need to alloc=
ate more heap because it was not big enough? Do you want to pay this reallo=
cation? Do you want to pay the branch required to handle it?</div></div></b=
lockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><d=
iv>There is a solution to that, and it already works on every single compil=
er: alloca + forced inlining. What do you want to recreate something emulat=
ing that which will be both slower and larger code?<br></div><div></div></d=
iv></blockquote><div><div style=3D"background-color:rgb(255,255,255);text-d=
ecoration-style:initial;text-decoration-color:initial"><br></div><div style=
=3D"background-color:rgb(255,255,255);text-decoration-style:initial;text-de=
coration-color:initial">alloca uses the stack. If you run out of stack, get=
 a segfault if you&#39;re lucky. The comments in the code below mention tha=
t a second-stack can be of configurable size. It could also be auto-growing=
 with a little work.=C2=A0</div><div style=3D"background-color:rgb(255,255,=
255);text-decoration-style:initial;text-decoration-color:initial">=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"background-color:rgb(255,255,=
255);text-decoration-style:initial;text-decoration-color:initial;margin:0px=
 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr">=C2=A0<br></div></blockquote></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"><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div><div st=
yle=3D"color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><font face=
=3D"monospace, monospace"><span style=3D"color:rgb(0,0,255)">struct</span><=
span style=3D"color:rgb(0,0,0)"> second_stack_impl</span></font></div><div>=
<span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace">{</fon=
t></span></div><div><font face=3D"monospace, monospace"><span style=3D"colo=
r:rgb(0,0,0)"></span><span style=3D"color:rgb(0,0,255)">=C2=A0 static</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,255)=
">constexpr</span><span style=3D"color:rgb(0,0,0)"> std::size_t rounding =
=3D </span><span style=3D"color:rgb(0,0,255)">sizeof</span><span style=3D"c=
olor:rgb(0,0,0)">(std::uintptr_t); // etc</span></font></div><div><font fac=
e=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></span><span st=
yle=3D"color:rgb(0,0,255)">=C2=A0 static</span><span style=3D"color:rgb(0,0=
,0)"> </span><span style=3D"color:rgb(0,0,255)">constexpr</span><span style=
=3D"color:rgb(0,0,0)"> std::size_t size =3D </span><span style=3D"color:rgb=
(9,136,90)">1024</span><span style=3D"color:rgb(0,0,0)"> * </span><span sty=
le=3D"color:rgb(9,136,90)">1024</span><span style=3D"color:rgb(0,0,0)">; //=
 or by runtime config</span></font></div><font face=3D"monospace, monospace=
"><br></font><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace,=
 monospace">=C2=A0 std::byte* alloc(std::size_t bytes)</font></span></div><=
div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace">=
=C2=A0 {</font></span></div><div><font face=3D"monospace, monospace"><span =
style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,128,0)">=C2=A0=
 =C2=A0 // round and allocate from second stack,</span></font></div><div><f=
ont face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></span><=
span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // store size</span></font>=
</div><div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,1=
28,0)">=C2=A0 =C2=A0 // return address of allocated data</span></font></div=
><div><span style=3D"color:rgb(0,0,0)"><font face=3D"monospace, monospace">=
=C2=A0 }</font></span></div><font face=3D"monospace, monospace"><br></font>=
<div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"><=
/span><span style=3D"color:rgb(0,0,255)">=C2=A0 void</span><span style=3D"c=
olor:rgb(0,0,0)"> dealloc()</span></font></div><div><span style=3D"color:rg=
b(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 {</font></span></div><=
div><font face=3D"monospace, monospace"><span style=3D"color:rgb(0,0,0)"></=
span><span style=3D"color:rgb(0,128,0)">=C2=A0 =C2=A0 // recover size from =
stack top and </span></font></div><div><font face=3D"monospace, monospace">=
<span style=3D"color:rgb(0,0,0)"></span><span style=3D"color:rgb(0,128,0)">=
=C2=A0 =C2=A0 // return to stack</span></font></div><div><span style=3D"col=
or:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 }</font></span></=
div><font face=3D"monospace, monospace"><br></font><div><span style=3D"colo=
r:rgb(0,0,0)"><font face=3D"monospace, monospace">=C2=A0 std::array&lt;std:=
:byte, size&gt; storage;</font></span></div><div><span style=3D"color:rgb(0=
,0,0)"><font face=3D"monospace, monospace">=C2=A0 std::byte* top =3D storag=
e.data() + size;</font></span></div><div><span style=3D"color:rgb(0,0,0)"><=
font face=3D"monospace, monospace">};</font></span></div><font face=3D"mono=
space, monospace"><span style=3D"color:rgb(0,128,0);font-size:small;backgro=
und-color:rgb(255,255,254);float:none;display:inline"><div style=3D"color:r=
gb(0,0,0);background-color:rgb(255,255,254)"><font face=3D"monospace, monos=
pace"><span style=3D"color:rgb(0,128,0);font-size:small;background-color:rg=
b(255,255,254);float:none;display:inline"><br></span></font></div>// gcc us=
es the fs register to address thread_local data. Zero overhead.</span><div =
style=3D"color:rgb(0,0,0);background-color:rgb(255,255,254)"><span style=3D=
"color:rgb(0,0,255)">thread_local</span> second_stack_impl second_stack;<br=
></div></font><br></div></div></div></div></blockquote><div><br></div><div>=
Oups, your max size was not enough...</div></div></blockquote><div><br></di=
v><div>noted above.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>Also, TLS has always an overhead. It&#39;s close to zer=
o when compiling statically, but not everybody compile statically. And even=
 in that case, your solution will be slower than just using alloca.<br></di=
v></div></blockquote><div><br></div><div>inside out functions that expose a=
lloca()-allocated objects require static compilation at the very least. TLS=
 has no overhead on gcc. Furthermore, with the as-if and strict-aliasing ru=
les, even if it did, it would be minimal. c++ is defined in terms of an abs=
tract object model, not a strict act-on-memory model.</div><div><br></div><=
div>In addition, what happens if there are more than one alloca-allocated a=
nd life-extended objects? How do we track destruction order? We have to, ot=
herwise interrupts and intermediate stack use will clobber our objects. The=
re is no realloc equivalent with alloca. You don&#39;t want to be using it =
in a loop, ever.</div><div><br></div><div>Please note that alloca() is <u>n=
ot</u> part of the posix standard. It&#39;s a GNU extension.</div><div>=C2=
=A0</div><div>I agree that pre-allocating storage can be a useful optimisat=
ion.=C2=A0</div><div>I am fine with that storage being on the stack.</div><=
div>I agree that it&#39;s nice to hide that detail behind an abstraction.=
=C2=A0</div><div>I think we already have a number of ways to do it.=C2=A0</=
div><div>I&#39;m happy to explore the pros and cons with you.=C2=A0</div><d=
iv>I don&#39;t think &quot;inline!&quot; looks like the right way.</div><di=
v>I don&#39;t think it&#39;s useful to enter discussions on whether optimis=
ation A is better than optimisation B without some means of measurement.</d=
iv><div><br></div><div>I think we share a lot of common ground.=C2=A0 =C2=
=A0=C2=A0<br></div><div>=C2=A0</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"><div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><div style=3D"color:rgb(=
0,0,0);background-color:rgb(255,255,254)"></div><br></div><div>=C2=A0</div>=
<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"><div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/393f701c-0240-4130-8918-0b1dbe924452%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofollow" t=
arget=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-proposa=
ls/393f701c-0240-4130-8918-0b1dbe924452%40isocpp.org</a>.<br>
</blockquote></div></div>
</blockquote></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1ca6a29e-8e5c-4cce-8b8f-61435c76d124%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1ca6a29e-8e5c-=
4cce-8b8f-61435c76d124%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hYwax0GwPaQk_9MP0tf3pNYojKuoi%2=
BdR-gBiieVPga%2Baw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hYwax0G=
wPaQk_9MP0tf3pNYojKuoi%2BdR-gBiieVPga%2Baw%40mail.gmail.com</a>.<br />

--0000000000003747a30570cc5173--

.