220 17331 <c33d5ae6-9cb6-439c-86b7-5c863e80e0f9@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Alexander Marinov <sasho648@mail.bg>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: constexpr function arguments
Date: Sun, 12 Apr 2015 08:34:51 -0700 (PDT)
Lines: 781
Approved: news@gmane.org
Message-ID: <c33d5ae6-9cb6-439c-86b7-5c863e80e0f9@isocpp.org>
References: <1799313.qMEWgUf3zn@lastique-pc> <2811449.Gbl9WO8oH6@lastique-pc> <dabe9c33-4346-45ba-a521-0ab6e0df77e7@isocpp.org>
 <2768024.05U7k9dJ4x@lastique-pc>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_299_1292937151.1428852891915"
X-Trace: ger.gmane.org 1428852898 5442 80.91.229.3 (12 Apr 2015 15:34:58 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 12 Apr 2015 15:34:58 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDBNZXHN2QPRBHFBVKUQKGQEQCTHZFQ@isocpp.org Sun Apr 12 17:34:57 2015
Return-path: <std-proposals+bncBDBNZXHN2QPRBHFBVKUQKGQEQCTHZFQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pd0-f198.google.com ([209.85.192.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDBNZXHN2QPRBHFBVKUQKGQEQCTHZFQ@isocpp.org>)
	id 1YhJuR-0001Eo-Hv
	for gclcip-std-proposals@m.gmane.org; Sun, 12 Apr 2015 17:34:56 +0200
Original-Received: by pdlj11 with SMTP id j11sf120728511pdl.0
        for <gclcip-std-proposals@m.gmane.org>; Sun, 12 Apr 2015 08:34:53 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:content-type:x-original-sender:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=xIKXvAMISsz+kB7PXOjklICofJqClGbMwO8cgDGt5fQ=;
        b=Y98wZo/jRRY+OlhTGBracWmSA7V1pGxC+ad7hIADPSRMtxgqk1+9d8hnlSH8rcHhw0
         UnUAZnApk3x22yRiOWhdAHgnqRemEWwUdpcmOsmdWPsHjaUhyWzXqoRBPtfVZ9yT/BX+
         /T1NX256JsvS3taHET9w5sn6G3Ww0kJoRFtNHKH8YTR9q7j/kDX1lDqm+CTgvFbaRtuY
         5piSiNrygSKyVVCaY1JSMJhjIm2GNP/02JUKEi3eMefzM86SRxZ04aVUpeO2T4U8XNE/
         jwCUb5OmQp35y9ir+PNYHAPO1+UbGAg1GBdcYt1a309MnxEuCwY9QEPcznI9w9GxKKjS
         iPWQ==
X-Gm-Message-State: ALoCoQn3jiMiSao8fleMd3GyIPRPQJjnM76SB3NoQi8hHcI2P+zqmz3c6F5K7Z7NdWnnupeGdKUW
X-Received: by 10.66.101.100 with SMTP id ff4mr14628198pab.24.1428852893479;
        Sun, 12 Apr 2015 08:34:53 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.140.96.67 with SMTP id j61ls2397958qge.67.gmail; Sun, 12 Apr
 2015 08:34:52 -0700 (PDT)
X-Received: by 10.140.91.47 with SMTP id y44mr118908qgd.39.1428852892546;
        Sun, 12 Apr 2015 08:34:52 -0700 (PDT)
In-Reply-To: <2768024.05U7k9dJ4x@lastique-pc>
X-Original-Sender: sasho648@mail.bg
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:17331
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/17331>

------=_Part_299_1292937151.1428852891915
Content-Type: multipart/alternative; 
	boundary="----=_Part_300_7672864.1428852891915"

------=_Part_300_7672864.1428852891915
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F, 12 =D0=B0=D0=BF=D1=80=D0=B8=D0=BB 201=
5 =D0=B3., 17:16:09 UTC+3, Andrey Semashev =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=
=D0=B0:
>
> On Sunday 12 April 2015 06:13:35 Alexander Marinov wrote:=20
> > You read my proposal - it does the same thing you want even if you don'=
t=20
> > fully understand it.=20
>
> I did read it, and I still don't think it covers my case. In fact, I'm no=
t=20
> sure I agree with your proposal.=20
>
> > Actually 'constexpr' is a useless keyword - it adds nothing to 'inline'=
=20
> > functions which most compilers already optimize out and evaluate at=20
> > compile-time if possible.=20
>
> It adds a _requirement_ on the function to be evaluated at compile time,=
=20
> provided that its arguments are also constexpr. It also adds certain=20
> restrictions on the function body. There is no such requirement or=20
> restrictions for inline functions, and in fact even the most trivial=20
> inline=20
> functions are allowed to not be inlined or optimized. And this is the cas=
e=20
> in=20
> debug builds, for instance, when compilers don't do any inlining at all=
=20
> but=20
> are still bound to evaluate constexpr at compile time.=20
>

Actually it doesn't, neither 'constexpr' do. A call to 'constexpr' is done=
=20
the same way to a normal function so it's still a compiler decision if it's=
=20
going to evaluate it at compile-time. The only case where this is required=
=20
is when such function is instanced at place where constant-expression is=20
expected. I don't see any reason not to implicitly enable this feature to=
=20
'inline' functions too. Actually 'constexpr' functions are inline by=20
default. Examples of current standard:

constexpr /*imagine < this was not there */ inline int func(int a) { return=
=20
a * 4; }

//note the above declaration is the same if 'inline' was not there because=
=20
it's implicitly implied by 'constexpr'

int b;

int main(){
    float arr[func(b)]; //here 'func' should be evaluated at compile-time=
=20
but this is currently not possible - error


    int runtime =3D func(b); //ok, here 'func(b)' is evaluated at 'run-time=
'


    float arr1[func(9)]; //ok, here 'func(b)' is evaluated at 'compile-time=
'

    int compilerdec =3D func(9); //ok, here 'func(b)' is evaluated either a=
t=20
'run-time' or 'compile-time'

}

Note that the above is a real working example. You can test it online here=
=20
<http://melpon.org/wandbox/permlink/xtDvFqwUcIB2nFVT>.

About the function requirements - I really think that they are decided on=
=20
no real basis and I that they should be removed all. At first 'constexpr'=
=20
function should consist only of a return statement, later this requirement=
=20
was lifted. I think now it's high-time to lift them all.
=20

>
> What you're suggesting is essentially mandate a certain level of compiler=
=20
> optimization as a language feature. I'm not sure this is a good idea.=20
>
> > The part which fulfill your idea is 'inline' variables which are=20
> guaranteed=20
> > to be evaluated at run-time (as template parameters)=20
>
> I assume, you meant "compile-time" here?=20
>

Yeah - sorry - common mistake of mine.
=20

>
> > and more specially=20
> > 'inline' function parameters (which imply that the function they=20
> > declare/define is 'inline' because templates can't be defined at=20
> different=20
> > TU).=20
> >=20
> > So your example will look like this by using my construct:=20
> >=20
> > template< typename T >=20
> >   void atomic<T>::store(T val, inline memory_order order)=20
> >   {=20
> >     switch (order) // order is always constexpr=20
> >     {=20
> >       // implementations with different memory ordering guarantees=20
> >     }=20
> >=20
> >   }=20
> >=20
> > With the exact same semantics you want. Function parameter 'order' will=
=20
> > accept only constant-expressions and it will be evaluated at=20
> compile-time.=20
>
> Yes, that would be my proposal, although I would still use constexpr=20
> keyword.=20
> I didn't find inline variables in your proposal thread, sorry if I missed=
=20
> it.=20
>

Why polite the source code with another new keyword as we can reuse an=20
existing one.
=20

>
> > Actually those semantics are possible now too but have different=20
> > syntax(etc. by using template parameters):=20
> >=20
> > template< typename T, memory_order order >=20
> >   void atomic<T>::store(T val)=20
> >   {=20
> >     switch (order) // order is always constexpr=20
> >     {=20
> >       // implementations with different memory ordering guarantees=20
> >     }=20
> >=20
> >   }=20
>
> Sure. In fact, I would have defined std::atomic interface this way myself=
=20
> in=20
> the first place. I guess, we have it defined the way it is to support=20
> C-style=20
> interface? Anyway, we have what we have, and my proposal attempts to=20
> improve=20
> it.=20
>
> > =D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F, 12 =D0=B0=D0=BF=D1=80=D0=B8=D0=BB=
 2015 =D0=B3., 15:29:21 UTC+3, Andrey Semashev =D0=BD=D0=B0=D0=BF=D0=B8=D1=
=81=D0=B0:=20
> > > On Sunday 12 April 2015 05:09:29 Alexander Marinov wrote:=20
> > > > I already sketched the details of this idea. You can read it here=
=20
> > > > <=20
> > >=20
> > >=20
> https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/RTss7U=
y=20
> > > l=20
> > >=20
> > > > zgQ>. Only someone needs to write a proposal and/or implement it as=
=20
> a=20
> > >=20
> > > demo=20
> > >=20
> > > > in some open-source compiler (GCC or Clang).=20
> > >=20
> > > No, I don't think your proposal is related to my idea. I'm not trying=
=20
> to=20
> > > make=20
> > > a function constexpr, I'm trying to propagate compile-time nature of=
=20
> some=20
> > > of=20
> > > its arguments to its body, which is executed in run time.=20
> > >=20
> > > (offtopic: And I do think that inline and constexpr are different=20
> > > properties=20
> > > of the code, even though they are somewhat related on the=20
> implementation=20
> > > side;=20
> > > I do not think they should be mixed together in a single keyword.)=20
> > >=20
> > > > =D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F, 12 =D0=B0=D0=BF=D1=80=D0=B8=
=D0=BB 2015 =D0=B3., 13:33:17 UTC+3, Andrey Semashev =D0=BD=D0=B0=D0=BF=D0=
=B8=D1=81=D0=B0:=20
> > > > > Hi,=20
> > > > >=20
> > > > > I wonder if constexpr function arguments would be a useful=20
> addition to=20
> > >=20
> > > the=20
> > >=20
> > > > > standard. Consider this part of std::atomic interface:=20
> > > > >   template< typename T >=20
> > > > >   void atomic<T>::store(T val, memory_order order)=20
> > > > >   {=20
> > > > >  =20
> > > > >     switch (order)=20
> > > > >     {=20
> > > > >    =20
> > > > >       // implementations with different memory ordering guarantee=
s=20
> > > > >    =20
> > > > >     }=20
> > > > >  =20
> > > > >   }=20
> > > > >=20
> > > > > The function itself is not constexpr because the implementation=
=20
> has a=20
> > > > > runtime=20
> > > > > side effect. However the memory order argument is always constant=
=20
> in=20
> > > > > normal=20
> > > > > uses and the implementation could have had benefitted from knowin=
g=20
> > >=20
> > > this=20
> > >=20
> > > > > constant at compile time. The current standard does not offer=20
> means=20
> > >=20
> > > for=20
> > >=20
> > > > > that,=20
> > > > > so you're out of luck if the compiler is not smart enough to=20
> propagate=20
> > > > > this=20
> > > > > constexpr hint behind the scenes. For the most part with compiler=
s=20
> I=20
> > >=20
> > > have=20
> > >=20
> > > > > experience with (gcc, icl, msvc) this only works when the compile=
r=20
> is=20
> > >=20
> > > able=20
> > >=20
> > > > > to=20
> > > > > inline the function call.=20
> > > > >=20
> > > > > BTW, if anyone wonders if compiler intrinsics help here, no they=
=20
> > >=20
> > > don't.=20
> > >=20
> > > > > With=20
> > > > >=20
> > > > > the code similar to this:=20
> > > > >   template< typename T >=20
> > > > >   void atomic<T>::store(T val, memory_order order)=20
> > > > >   {=20
> > > > >  =20
> > > > >     __atomic_store_n(&m_value, val, order);=20
> > > > >  =20
> > > > >   }=20
> > > > >=20
> > > > > gcc and icl simply fall back to memory_order_seq_cst regardless o=
f=20
> the=20
> > > > > specified order if they cannot inline the function. This always=
=20
> > >=20
> > > happens in=20
> > >=20
> > > > > debug, for instance.=20
> > > > >=20
> > > > > What I'm thinking is if we could require some argument to be=20
> constexpr=20
> > >=20
> > > and=20
> > >=20
> > > > > pass that 'compile-timeness' hint to the function body, the=20
> > >=20
> > > implementation=20
> > >=20
> > > > > could optimize better. For example:=20
> > > > >   template< typename T >=20
> > > > >   void atomic<T>::store(T val, constexpr memory_order order)=20
> > > > >   {=20
> > > > >  =20
> > > > >     switch (order) // order is always constexpr=20
> > > > >     {=20
> > > > >    =20
> > > > >       // implementations with different memory ordering guarantee=
s=20
> > > > >    =20
> > > > >     }=20
> > > > >  =20
> > > > >   }=20
> > > > >=20
> > > > > In this case the switch/case would always be optimized to a singl=
e=20
> > >=20
> > > case.=20
> > >=20
> > > > > And=20
> > > > > the intrinsic-based version would also work as intended. Also, if=
=20
> we=20
> > >=20
> > > have=20
> > >=20
> > > > > a=20
> > > > > non-constexpr overload of this function we would also support=20
> calling=20
> > >=20
> > > with=20
> > >=20
> > > > > a=20
> > > > > runtime value of the memory order (not that it would be of much=
=20
> use=20
> > > > > though).=20
> > > > >=20
> > > > > I understand this would have consequences on the ABI because=20
> constexpr=20
> > > > > arguments essentiall require to duplicate the function body for=
=20
> each=20
> > > > > constant=20
> > > > > argument value. It's not a big problem though because we already=
=20
> do=20
> > >=20
> > > that=20
> > >=20
> > > > > for=20
> > > > > non-type template parameters.=20
> > > > >=20
> > > > > Opinions?=20
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_300_7672864.1428852891915
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F, 12 =D0=B0=D0=
=BF=D1=80=D0=B8=D0=BB 2015 =D0=B3., 17:16:09 UTC+3, Andrey Semashev =D0=BD=
=D0=B0=D0=BF=D0=B8=D1=81=D0=B0:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
>On Sunday 12 April 2015 06:13:35 Alexander Marinov wrote:
<br>&gt; You read my proposal - it does the same thing you want even if you=
 don't
<br>&gt; fully understand it.
<br>
<br>I did read it, and I still don't think it covers my case. In fact, I'm =
not=20
<br>sure I agree with your proposal.
<br>
<br>&gt; Actually 'constexpr' is a useless keyword - it adds nothing to 'in=
line'
<br>&gt; functions which most compilers already optimize out and evaluate a=
t
<br>&gt; compile-time if possible.
<br>
<br>It adds a _requirement_ on the function to be evaluated at compile time=
,=20
<br>provided that its arguments are also constexpr. It also adds certain=20
<br>restrictions on the function body. There is no such requirement or=20
<br>restrictions for inline functions, and in fact even the most trivial in=
line=20
<br>functions are allowed to not be inlined or optimized. And this is the c=
ase in=20
<br>debug builds, for instance, when compilers don't do any inlining at all=
 but=20
<br>are still bound to evaluate constexpr at compile time.
<br></blockquote><div><br></div><div>Actually it doesn't, neither 'constexp=
r' do. A call to 'constexpr' is done the same way to a normal function so i=
t's still a compiler decision if it's going to evaluate it at compile-time.=
 The only case where this is required is when such function is instanced at=
 place where constant-expression is expected. I don't see any reason not to=
 implicitly enable this feature to 'inline' functions too. Actually 'conste=
xpr' functions are inline by default. Examples of current standard:<br><br>=
</div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 1=
87, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">/*imagine &lt; this was not there */</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">inline</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> a</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;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> a </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">4</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;" class=3D"styled-by-prettify">}</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//note the above declaration=
 is the same if 'inline' was not there because it's implicitly implied by '=
constexpr'</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">in=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> main</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(){</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">float</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> arr</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">[</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">func</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)];</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #800;" class=3D"styled-by-prettify">//here 'func' should be =
evaluated at compile-time but this is currently not possible - error</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br>&nbsp=
; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">i=
nt</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> runtime=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> func</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">b</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: #800;" class=3D=
"styled-by-prettify">//ok, here 'func(b)' is evaluated at 'run-time'</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br>&nbsp=
; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">f=
loat</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> arr1<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">func</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">9</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: #800;" class=3D"style=
d-by-prettify">//ok, here 'func(b)' is evaluated at 'compile-time'</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbs=
p; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> compilerdec <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> func</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">9</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">//ok, here 'func(b)' is evaluated either at 'run-time' or =
'compile-time'</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span></div></code></div><div><br></div></div><div>Note that the above =
is a real working example. You can test it online <a href=3D"http://melpon.=
org/wandbox/permlink/xtDvFqwUcIB2nFVT">here</a>.</div><div><br></div><div>A=
bout the function requirements - I really think that they are decided on no=
 real basis and I that they should be removed all. At first 'constexpr' fun=
ction should consist only of a return statement, later this requirement was=
 lifted. I think now it's high-time to lift them all.</div><div>&nbsp;</div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;">
<br>What you're suggesting is essentially mandate a certain level of compil=
er=20
<br>optimization as a language feature. I'm not sure this is a good idea.
<br>
<br>&gt; The part which fulfill your idea is 'inline' variables which are g=
uaranteed
<br>&gt; to be evaluated at run-time (as template parameters)
<br>
<br>I assume, you meant "compile-time" here?
<br></blockquote><div><br></div><div>Yeah - sorry - common mistake of mine.=
</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; and more specially
<br>&gt; 'inline' function parameters (which imply that the function they
<br>&gt; declare/define is 'inline' because templates can't be defined at d=
ifferent
<br>&gt; TU).
<br>&gt;=20
<br>&gt; So your example will look like this by using my construct:
<br>&gt;=20
<br>&gt; template&lt; typename T &gt;
<br>&gt; &nbsp; void atomic&lt;T&gt;::store(T val, inline memory_order orde=
r)
<br>&gt; &nbsp; {
<br>&gt; &nbsp; &nbsp; switch (order) // order is always constexpr
<br>&gt; &nbsp; &nbsp; {
<br>&gt; &nbsp; &nbsp; &nbsp; // implementations with different memory orde=
ring guarantees
<br>&gt; &nbsp; &nbsp; }
<br>&gt;=20
<br>&gt; &nbsp; }
<br>&gt;=20
<br>&gt; With the exact same semantics you want. Function parameter 'order'=
 will
<br>&gt; accept only constant-expressions and it will be evaluated at compi=
le-time.
<br>
<br>Yes, that would be my proposal, although I would still use constexpr ke=
yword.=20
<br>I didn't find inline variables in your proposal thread, sorry if I miss=
ed it.
<br></blockquote><div><br></div><div>Why polite the source code with anothe=
r new keyword as we can reuse an existing one.</div><div>&nbsp;</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; Actually those semantics are possible now too but have different
<br>&gt; syntax(etc. by using template parameters):
<br>&gt;=20
<br>&gt; template&lt; typename T, memory_order order &gt;
<br>&gt; &nbsp; void atomic&lt;T&gt;::store(T val)
<br>&gt; &nbsp; {
<br>&gt; &nbsp; &nbsp; switch (order) // order is always constexpr
<br>&gt; &nbsp; &nbsp; {
<br>&gt; &nbsp; &nbsp; &nbsp; // implementations with different memory orde=
ring guarantees
<br>&gt; &nbsp; &nbsp; }
<br>&gt;=20
<br>&gt; &nbsp; }
<br>
<br>Sure. In fact, I would have defined std::atomic interface this way myse=
lf in=20
<br>the first place. I guess, we have it defined the way it is to support C=
-style=20
<br>interface? Anyway, we have what we have, and my proposal attempts to im=
prove=20
<br>it.
<br>
<br>&gt; =D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F, 12 =D0=B0=D0=BF=D1=80=D0=B8=
=D0=BB 2015 =D0=B3., 15:29:21 UTC+3, Andrey Semashev =D0=BD=D0=B0=D0=BF=D0=
=B8=D1=81=D0=B0:
<br>&gt; &gt; On Sunday 12 April 2015 05:09:29 Alexander Marinov wrote:
<br>&gt; &gt; &gt; I already sketched the details of this idea. You can rea=
d it here
<br>&gt; &gt; &gt; &lt;
<br>&gt; &gt;=20
<br>&gt; &gt; <a href=3D"https://groups.google.com/a/isocpp.org/forum/#!top=
ic/std-proposals/RTss7Uy" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D'https://groups.google.com/a/isocpp.org/forum/#!topic/std-prop=
osals/RTss7Uy';return true;" onclick=3D"this.href=3D'https://groups.google.=
com/a/isocpp.org/forum/#!topic/std-proposals/RTss7Uy';return true;">https:/=
/groups.google.com/a/<wbr>isocpp.org/forum/#!topic/std-<wbr>proposals/RTss7=
Uy</a>
<br>&gt; &gt; l
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; zgQ&gt;. Only someone needs to write a proposal and/or i=
mplement it as a
<br>&gt; &gt;=20
<br>&gt; &gt; demo
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; in some open-source compiler (GCC or Clang).
<br>&gt; &gt;=20
<br>&gt; &gt; No, I don't think your proposal is related to my idea. I'm no=
t trying to
<br>&gt; &gt; make
<br>&gt; &gt; a function constexpr, I'm trying to propagate compile-time na=
ture of some
<br>&gt; &gt; of
<br>&gt; &gt; its arguments to its body, which is executed in run time.
<br>&gt; &gt;=20
<br>&gt; &gt; (offtopic: And I do think that inline and constexpr are diffe=
rent
<br>&gt; &gt; properties
<br>&gt; &gt; of the code, even though they are somewhat related on the imp=
lementation
<br>&gt; &gt; side;
<br>&gt; &gt; I do not think they should be mixed together in a single keyw=
ord.)
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; =D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F, 12 =D0=B0=D0=BF=D1=
=80=D0=B8=D0=BB 2015 =D0=B3., 13:33:17 UTC+3, Andrey Semashev =D0=BD=D0=B0=
=D0=BF=D0=B8=D1=81=D0=B0:
<br>&gt; &gt; &gt; &gt; Hi,
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; I wonder if constexpr function arguments would be a=
 useful addition to
<br>&gt; &gt;=20
<br>&gt; &gt; the
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; standard. Consider this part of std::atomic interfa=
ce:
<br>&gt; &gt; &gt; &gt; &nbsp; template&lt; typename T &gt;
<br>&gt; &gt; &gt; &gt; &nbsp; void atomic&lt;T&gt;::store(T val, memory_or=
der order)
<br>&gt; &gt; &gt; &gt; &nbsp; {
<br>&gt; &gt; &gt; &gt; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; switch (order)
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; {
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; &nbsp; // implementations with differ=
ent memory ordering guarantees
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; }
<br>&gt; &gt; &gt; &gt; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; }
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; The function itself is not constexpr because the im=
plementation has a
<br>&gt; &gt; &gt; &gt; runtime
<br>&gt; &gt; &gt; &gt; side effect. However the memory order argument is a=
lways constant in
<br>&gt; &gt; &gt; &gt; normal
<br>&gt; &gt; &gt; &gt; uses and the implementation could have had benefitt=
ed from knowing
<br>&gt; &gt;=20
<br>&gt; &gt; this
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; constant at compile time. The current standard does=
 not offer means
<br>&gt; &gt;=20
<br>&gt; &gt; for
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; that,
<br>&gt; &gt; &gt; &gt; so you're out of luck if the compiler is not smart =
enough to propagate
<br>&gt; &gt; &gt; &gt; this
<br>&gt; &gt; &gt; &gt; constexpr hint behind the scenes. For the most part=
 with compilers I
<br>&gt; &gt;=20
<br>&gt; &gt; have
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; experience with (gcc, icl, msvc) this only works wh=
en the compiler is
<br>&gt; &gt;=20
<br>&gt; &gt; able
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; to
<br>&gt; &gt; &gt; &gt; inline the function call.
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; BTW, if anyone wonders if compiler intrinsics help =
here, no they
<br>&gt; &gt;=20
<br>&gt; &gt; don't.
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; With
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; the code similar to this:
<br>&gt; &gt; &gt; &gt; &nbsp; template&lt; typename T &gt;
<br>&gt; &gt; &gt; &gt; &nbsp; void atomic&lt;T&gt;::store(T val, memory_or=
der order)
<br>&gt; &gt; &gt; &gt; &nbsp; {
<br>&gt; &gt; &gt; &gt; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; __atomic_store_n(&amp;m_value, val, o=
rder);
<br>&gt; &gt; &gt; &gt; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; }
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; gcc and icl simply fall back to memory_order_seq_cs=
t regardless of the
<br>&gt; &gt; &gt; &gt; specified order if they cannot inline the function.=
 This always
<br>&gt; &gt;=20
<br>&gt; &gt; happens in
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; debug, for instance.
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; What I'm thinking is if we could require some argum=
ent to be constexpr
<br>&gt; &gt;=20
<br>&gt; &gt; and
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; pass that 'compile-timeness' hint to the function b=
ody, the
<br>&gt; &gt;=20
<br>&gt; &gt; implementation
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; could optimize better. For example:
<br>&gt; &gt; &gt; &gt; &nbsp; template&lt; typename T &gt;
<br>&gt; &gt; &gt; &gt; &nbsp; void atomic&lt;T&gt;::store(T val, constexpr=
 memory_order order)
<br>&gt; &gt; &gt; &gt; &nbsp; {
<br>&gt; &gt; &gt; &gt; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; switch (order) // order is always con=
stexpr
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; {
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; &nbsp; // implementations with differ=
ent memory ordering guarantees
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; &nbsp; }
<br>&gt; &gt; &gt; &gt; &nbsp;=20
<br>&gt; &gt; &gt; &gt; &nbsp; }
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; In this case the switch/case would always be optimi=
zed to a single
<br>&gt; &gt;=20
<br>&gt; &gt; case.
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; And
<br>&gt; &gt; &gt; &gt; the intrinsic-based version would also work as inte=
nded. Also, if we
<br>&gt; &gt;=20
<br>&gt; &gt; have
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; a
<br>&gt; &gt; &gt; &gt; non-constexpr overload of this function we would al=
so support calling
<br>&gt; &gt;=20
<br>&gt; &gt; with
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; a
<br>&gt; &gt; &gt; &gt; runtime value of the memory order (not that it woul=
d be of much use
<br>&gt; &gt; &gt; &gt; though).
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; I understand this would have consequences on the AB=
I because constexpr
<br>&gt; &gt; &gt; &gt; arguments essentiall require to duplicate the funct=
ion body for each
<br>&gt; &gt; &gt; &gt; constant
<br>&gt; &gt; &gt; &gt; argument value. It's not a big problem though becau=
se we already do
<br>&gt; &gt;=20
<br>&gt; &gt; that
<br>&gt; &gt;=20
<br>&gt; &gt; &gt; &gt; for
<br>&gt; &gt; &gt; &gt; non-type template parameters.
<br>&gt; &gt; &gt; &gt;=20
<br>&gt; &gt; &gt; &gt; Opinions?
<br>
<br></blockquote></div>

<p></p>

-- <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+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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_300_7672864.1428852891915--
------=_Part_299_1292937151.1428852891915--

.
