220 39086 <f39dc947-2aa5-4471-a875-e55beaa62c71@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: florian.csdt@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: constexpr! or constexpr(false)?
Date: Wed, 11 Jul 2018 07:29:10 -0700 (PDT)
Lines: 536
Approved: news@gmane.org
Message-ID: <f39dc947-2aa5-4471-a875-e55beaa62c71@isocpp.org>
References: <b3ebfe97-48ae-4a85-b202-2dbf330dd76b@isocpp.org>
 <CAFk2RUZKeomj2cVywH3Bhpu+LCTNx09m6gVNxLvPiwceD8agNQ@mail.gmail.com>
 <303bf6d1-2f5a-4b50-b6c0-6d689300243c@isocpp.org> <CAOHCbite6NDoLNGA__iVZ7GCS9EYCavBcGPPiqWfd9DH0+qvBQ@mail.gmail.com>
 <e44c4cfc-b27f-4301-89c6-dbf894570db9@isocpp.org> <f9a97563-31dc-480a-8846-e83ede139c26@isocpp.org>
 <a8f4b2c0-d025-4973-98d7-6a60b8071068@isocpp.org> <20180711072840.5177422.61062.57260@gmail.com>
 <73b413ed-cfef-4174-ac91-51f1eff0274d@isocpp.org> <de2e2db8-03b3-464b-b9d6-f31bba3a1228@isocpp.org>
 <d7201ef1-1e7b-4735-bd84-8e81b3983d10@isocpp.org> <faa625d2-380a-4eff-aa14-e26f20f03d1b@isocpp.org>
 <CALvx3hb=0XjVACgSdNO6gnUT_whA3pFbRrYQs4WP5PVhEi1Mmg@mail.gmail.com> <07767bd5-cd9f-4b9a-bee4-076ab043ccaa@isocpp.org>
 <CALvx3hbvsBe6o-EW9=K=0NmvteuHphGOotYScrGEG8eMjYj8Kw@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_128606_854936511.1531319350762"
X-Trace: blaine.gmane.org 1531319231 11102 195.159.176.226 (11 Jul 2018 14:27:11 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Wed, 11 Jul 2018 14:27:11 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC26HM4V3MIRBN5ITDNAKGQEFOKSTXA@isocpp.org Wed Jul 11 16:27:07 2018
Return-path: <std-proposals+bncBC26HM4V3MIRBN5ITDNAKGQEFOKSTXA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw0-f199.google.com ([209.85.161.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC26HM4V3MIRBN5ITDNAKGQEFOKSTXA@isocpp.org>)
	id 1fdG57-0002fx-S4
	for gclcip-std-proposals@m.gmane.org; Wed, 11 Jul 2018 16:27:02 +0200
Original-Received: by mail-yw0-f199.google.com with SMTP id q141-v6sf12063489ywg.5
        for <gclcip-std-proposals@m.gmane.org>; Wed, 11 Jul 2018 07:29:13 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=661pzMRxbe1QPAd5FJqtZuT+kbVcvnKO4PnHhWZOP2k=;
        b=q4+0WBG9hsWeq+HcgXcuiuq0edD3IVlu/D/AJCrEa065eobaJaHhhDBEB7+XQqH2vZ
         u2deHPY90DoJxZmmlvthmgytQqbhKmJ0ONEl+aM4MFvdRHZ/a5hB8pP1eW7CCYmsbPav
         QHVjgON8MEchqV8KmJxeg10gfqzFQru9NwmeD32j4y9t4/BrUtMsT5ywmx+MBdbC2OAa
         Nf++VtG1pSOzhRG9rb4JeZ5xNdbAsfcI32oWMxarmGe/Yiy86wwotao1f85NxZq02HLl
         QhfNmhWAUGdpak7GtQqOpmiYrEO4DiZCkgCTdqAodg0SUcWNlChJv2Nce10vfNdz4m3b
         wd7A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=661pzMRxbe1QPAd5FJqtZuT+kbVcvnKO4PnHhWZOP2k=;
        b=Ow9U1oPSdf6JuaRRzjRnKHXiL6XLDREhcbRtIgPN/NCLsugBjHNIRaUQl0ONo01fNj
         7I+B0vX72jAbYvfUYdAwyORZ/SfF1cFrijwD2aYjsoxv11ZyyW5qrMYNprc+XROGahZE
         XRfrvNhVn9ADepHHhXOELVLxllvkDidnUGLsEWtXuRNlRBHZA42YGw/mjH9L/PbVl9qw
         qLtuAQcnSCZJjq6WR4ulpPJ9Gwgk/hqkEKHUtHNC5VqZ6ID4YxZW0Zn0FeDA9+k3kQil
         Ta0h5nNFPJnjGtJbDeYBLpzgRAN5yHrq9xfk+NX+Vi+OARw/881NLnyu6p1uEJfDQwHT
         26yw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=661pzMRxbe1QPAd5FJqtZuT+kbVcvnKO4PnHhWZOP2k=;
        b=ZYmjJ4qa2wZYbhWtlDbzWf7U/MVf7A2VvILliXTfkCeayUCunJoHFLfUt8+zTfqZbg
         it7NW3TPXFy/gfwIYZKa7wZ/l+L+CjQw/lLhJ+GbfNAWXx1ghjDOu7OGmGipbhdH/NtX
         ncQysh0f7KWdnyOaJOJyXMOjgEpFLQh/5hjdhPIcyOWCQ2RUloV/tpO47BmxRUKtp0tF
         VW6gKztn3/zk8fQforUj0qmR0+PGEAIY4bUsoGj+riVNP32w5V468c9bCHXO2cM5Zr+Q
         cdu9lb2fUysXdl4aHZ6+7umVEWDrf2NoYlcX9EnMOaB5AsutGl+AqAhOhWYeSpAsrM57
         RXDQ==
X-Gm-Message-State: APt69E3TFnO5uvs81KQQoCnqKMOJs3Y/A6itj2w7yvorDBrpX/m8LWKr
	2M7OhF8DfwCxy2Z03nyb3lpaQg==
X-Google-Smtp-Source: AAOMgpdrgDmRwomqYIKu2iWoFRV8ZzeNdcjB63DPO85n2od17J6HZhkMLj9M6Npfv90rFgzrNLth8w==
X-Received: by 2002:a25:9702:: with SMTP id d2-v6mr8762456ybo.17.1531319352520;
        Wed, 11 Jul 2018 07:29:12 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 2002:a25:68a:: with SMTP id 132-v6ls1316669ybg.8.gmail; Wed, 11
 Jul 2018 07:29:11 -0700 (PDT)
X-Received: by 2002:a5b:60f:: with SMTP id d15-v6mr3951446ybq.6.1531319351132;
        Wed, 11 Jul 2018 07:29:11 -0700 (PDT)
In-Reply-To: <CALvx3hbvsBe6o-EW9=K=0NmvteuHphGOotYScrGEG8eMjYj8Kw@mail.gmail.com>
X-Original-Sender: florian.csdt@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:39086
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/39086>

------=_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--

.
