Topic: inline variables
Author: David Krauss <potswa@gmail.com>
Date: Wed, 9 Apr 2014 16:17:26 +0800
Raw View
--Apple-Mail=_11185D50-6C14-4E71-A26C-2251CF5C2607
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
Is there an existing proposal along these lines? There was some discussion =
previously in the thread "Variable templates and instantiation -- Is this w=
ell formed?" around Feb 6.
Promote the inline function-specifier to a storage-class-specifier. Like th=
read_local it may appear with static or extern. Like constexpr it causes ea=
ch declarator to require an initializer. It may appear in a member declarat=
ion but not a friend declaration. An inline variable does not name an objec=
t and hence it has no lifetime. It does not reserve any storage.
Evaluation of an inline variable results in evaluation of its initializer. =
The initializer is not evaluated by the declaration. (It is an unevaluated =
context, although that's a confusing way of putting it.) The facility may b=
e considered sugar for a nullary lambda object with lambda-capture [&], or =
as a member, for a nullary member function (static or nonstatic depending o=
n the static specifier). The effect is like lazy, repeated evaluation. Howe=
ver, unlike a lambda object it can only be evaluated, but never assigned, s=
o there is no potential expiration of captured references.
Evaluation of an inline variable of reference type produces an lvalue or xv=
alue. Non-reference types produce rvalues, unless the variable is declared =
constexpr, in which case the name is an lvalue referring to statically init=
ialized storage. (The linker sees such an object as having vague linkage.) =
This is essentially like adding an implicit lvalue reference qualifier to c=
onstexpr inline declarations (modulo decltype discrimination), and the rati=
onale is that there's no benefit to not doing so.
An extern constexpr inline variable may safely be ODR-used in multiple tran=
slation units. Since this is usually how constants are supposed to behave, =
it should be made more convenient and less verbose. The default linkage of =
constexpr inline is therefore external.=20
The ODR applies to inline variables analogously to inline functions: each T=
U must provide an identical definition, including the inline specifier.
A constexpr inline variable cannot be linked with a non-constexpr declarati=
on, no diagnostic required. There is no practical problem with allowing thi=
s, but neither is there any use case since constexpr inline provides a supe=
rior alternative, and it would break the uniformity of various rules.
Applications:
-- Migration of C macros such as stdin from <cstdio>, NULL from <cstddef>, =
and errno from <cerrno>. These could all be contained in std:: with depreca=
tion of the macro forms. The macros in the C-style headers (e.g. <stdio.h>)=
would simply fully qualify themselves (e.g. #define stdin ::std::stdin).
-- Tags and constants of class type such as std::piecewise_construct and st=
d::allocator_arg. Passing an empty class object of internal linkage by valu=
e inside an inline function violates the ODR, but passing by reference with=
external linkage (a la std::nothrow) may cause the ABI to require use of a=
parameter slot. Non-empty classes face a similar dilemma regarding compile=
-time value visibility. Even integer constants benefit. Currently it's ille=
gal to pass an integer constant through a perfect forwarding wrapper from a=
(multiply-defined) inline function.
-- Interface string constants, which are similar to constants of class type=
.. It becomes much easier use a literally-specified string as a template arg=
ument in a header, simply constexpr inline char s[] =3D "blah";. What's the=
next easiest way to accomplish that?
-- Migration of naked member interfaces to "properties" with getter-setter =
semantics. A member inline variable definition embedding a class-specifier =
containing a conversion function and an assignment operator serves as an id=
iomatic property.
-- Convenient member references, such as to provide named access to a base =
or sibling subobject, or a linked resource, without (de-facto) requiring st=
orage. For linked resources or cases where finding the subobject is nontriv=
ial, this also avoids potential fancy initialization order footwork.
-- Named local subexpressions. Although this may currently be done with lam=
bdas, an inline variable is more succinct than an inline function.
That's at least six, count-em 6 tough problems solved. The second one may r=
eally count as two or three. Quite some bang for the buck.
Yes there is some potential for abuse if the expression has side effects, b=
ut it's still less heinous than the equivalent macro. Anyone who hides side=
effects deserves what they get anyway. If it's really objectionable, the s=
pecifier can simply be disallowed at local scope with no damage to the othe=
r use-cases. (Side effects remain possible in declarations at other scopes,=
but the temptation is at local scope.)
As for implementation cost, most of the machinery is already in place in th=
e form of lambda functions and variable templates, which capture the propos=
ed vague linkage semantics. (Spoiler: this is the above-mentioned next easi=
est way to pass a compile-time string as a template argument, but it makes =
an obtuse idiom.)
--=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/.
--Apple-Mail=_11185D50-6C14-4E71-A26C-2251CF5C2607
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;">Is there an existing p=
roposal along these lines? There was some discussion previously in the thre=
ad "Variable templates and instantiation -- Is this well formed?” aro=
und Feb 6.<div><br><div><br></div><div>Promote the <font face=3D"Courier">i=
nline</font> <i>function-specifier</i> to a <i>storage-class-specifier</i>.=
Like <font face=3D"Courier">thread_local</font> it may appear with <font f=
ace=3D"Courier">static</font> or <font face=3D"Courier">extern</font>. Like=
<font face=3D"Courier">constexpr</font> it causes each declarator to =
require an initializer. It may appear in a member declaration but not a fri=
end declaration. An inline variable does not name an object and hence it ha=
s no lifetime. It does not reserve any storage.</div><div><br></div><div>Ev=
aluation of an inline variable results in evaluation of its initializer. Th=
e initializer is not evaluated by the declaration. (It is an unevaluated co=
ntext, although that’s a confusing way of putting it.) The facility m=
ay be considered sugar for a nullary lambda object with lambda-capture <fon=
t face=3D"Courier">[&]</font>, or as a member, for a nullary member fun=
ction (static or nonstatic depending on the <font face=3D"Courier">static</=
font> specifier). The effect is like lazy, repeated evaluation. Howeve=
r, unlike a lambda object it can only be evaluated, but never assigned, so =
there is no potential expiration of captured references.</div><div><br></di=
v><div>Evaluation of an inline variable of reference type produces an lvalu=
e or xvalue. Non-reference types produce rvalues, unless the variable is de=
clared <font face=3D"Courier">constexpr</font>, in which case the name is a=
n lvalue referring to statically initialized storage. (The linker sees such=
an object as having vague linkage.) This is essentially like adding an imp=
licit lvalue reference qualifier to <font face=3D"Courier">constexpr inline=
</font> declarations (modulo <font face=3D"Courier">decltype</font> discrim=
ination), and the rationale is that there’s no benefit to not doing s=
o.</div><div><br></div><div>An <font face=3D"Courier">extern constexpr inli=
ne</font> variable may safely be ODR-used in multiple translation unit=
s. Since this is usually how constants are supposed to behave, it should be=
made more convenient and less verbose. The default linkage of <font f=
ace=3D"Courier">constexpr inline</font> is therefore external. </=
div><div><br></div><div>The ODR applies to inline variables analogously to =
inline functions: each TU must provide an identical definition, including t=
he inline specifier.</div><div><br></div><div>A <font face=3D"Courier"=
>constexpr inline</font> variable cannot be linked with a non-constexpr dec=
laration, no diagnostic required. There is no practical problem with allowi=
ng this, but neither is there any use case since<font face=3D"Courier">&nbs=
p;constexpr inline</font> provides a superior alternative, and it=
would break the uniformity of various rules.</div><div><br></div><div>Appl=
ications:</div></div><div>— Migration of C macros such as <font face=
=3D"Courier">stdin</font> from <font face=3D"Courier"><cstdio></font>=
, <font face=3D"Courier">NULL</font> from <font face=3D"Courier"><cstdde=
f></font>, and <font face=3D"Courier">errno</font> from <font =
face=3D"Courier"><cerrno></font>. These could all be contained in <fo=
nt face=3D"Courier">std::</font> with deprecation of the macro forms. The m=
acros in the C-style headers (e.g. <font face=3D"Courier"><stdio.h></=
font>) would simply fully qualify themselves (e.g. <font face=3D"Courier">#=
define stdin ::std::stdin</font>).</div><div>— Tags and constants of =
class type such as <font face=3D"Courier">std::piecewise_construct</font> a=
nd <font face=3D"Courier">std::allocator_arg</font>. Passing an empty class=
object of internal linkage by value inside an inline function violates the=
ODR, but passing by reference with external linkage (a la <font face=3D"Co=
urier">std::nothrow</font>) may cause the ABI to require use of a parameter=
slot. Non-empty classes face a similar dilemma regarding compile-time valu=
e visibility. Even integer constants benefit. Currently it’s illegal =
to pass an integer constant through a perfect forwarding wrapper from a (mu=
ltiply-defined) inline function.</div><div>— Interface string constan=
ts, which are similar to constants of class type. It becomes much easier us=
e a literally-specified string as a template argument in a header, simply&n=
bsp;<font face=3D"Courier">constexpr inline char s[] =3D "blah";</font>. Wh=
at’s the next easiest way to accomplish that?</div><div>— Migra=
tion of naked member interfaces to “properties” with getter-set=
ter semantics. A member inline variable definition embedding a <i>class-spe=
cifier</i> containing a conversion function and an assignment operator serv=
es as an idiomatic property.</div><div>— Convenient member references=
, such as to provide named access to a base or sibling subobject, or a link=
ed resource, without (de-facto) requiring storage. For linked resources or =
cases where finding the subobject is nontrivial, this also avoids potential=
fancy initialization order footwork.</div><div>— Named local subexpr=
essions. Although this may currently be done with lambdas, an inline variab=
le is more succinct than an inline function.</div><div><br></div><div>That&=
rsquo;s at least six, count-em 6 tough problems solved. The second one may =
really count as two or three. Quite some bang for the buck.</div><div><br><=
/div><div>Yes there is some potential for abuse if the expression has side =
effects, but it’s still less heinous than the equivalent macro. Anyon=
e who hides side effects deserves what they get anyway. If it’s reall=
y objectionable, the specifier can simply be disallowed at local scope with=
no damage to the other use-cases. (Side effects remain possible in declara=
tions at other scopes, but the temptation is at local scope.)</div><div><br=
></div><div>As for implementation cost, most of the machinery is already in=
place in the form of lambda functions and variable templates, which captur=
e the proposed vague linkage semantics. (Spoiler: this is the above-mention=
ed next easiest way to pass a compile-time string as a template argument, b=
ut it makes an obtuse idiom.)</div><div><br></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail=_11185D50-6C14-4E71-A26C-2251CF5C2607--
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Wed, 9 Apr 2014 11:20:17 +0200
Raw View
--089e0111bf72e65f9e04f6989ba5
Content-Type: text/plain; charset=UTF-8
As someone using a lot local sub expressions (for clarity) but being
frustrated when I have to remove them for performance optimization (not
often but happen), I'm very interested.
Just to clarify, would this be valid?
struct A
{
inline auto value = access_value();
private:
int m_value = 0;
int& access_value() { /* some checks and
optional/lazy processing*/ return m_value; }
const int& access_value() const { /* some checks and optional/lazy
processing*/ return m_value; }
};
void print( const A& a )
{
std::cout << "A.value = " << a.value << std::endl; // execute
A::access_value() const version
}
int main()
{
A a;
a.value = 42; // execute A::access_value() non-const version returning
a reference
print( a );
const A& readonly_a = a;
readonly_a.value = 123; // ERROR: called A::access_value() const
version which return a const reference, non modifiable
}
My understanding is that if the expression is evaluated on variable use AND
if auto can be used in the inline variable declaration, then the compiler
can deduce which version of the function to call (const or not const).
Am I correct?
Also, is my use of public/private valid here?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0111bf72e65f9e04f6989ba5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra">As someone using a lot local su=
b expressions (for clarity) but being frustrated when I have to remove them=
for performance optimization (not often but happen), I'm very interest=
ed.</div>
<div class=3D"gmail_extra">Just to clarify, would this be valid?</div><div =
class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">struct A</div><d=
iv class=3D"gmail_extra">{</div><div class=3D"gmail_extra">=C2=A0 =C2=A0 in=
line auto value =3D access_value();</div>
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">private:</d=
iv><div class=3D"gmail_extra">=C2=A0 =C2=A0 int m_value =3D 0;</div><div cl=
ass=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 int&=
amp; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 access_value() =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0{ /* some checks and optional/lazy processing*/ =C2=A0return =
m_value; }</div>
<div class=3D"gmail_extra">=C2=A0 =C2=A0 const int& access_value() cons=
t { /* some checks and optional/lazy processing*/ =C2=A0return m_value; }</=
div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">};</div=
><div class=3D"gmail_extra">
<br></div><div class=3D"gmail_extra">void print( const A& a )</div><div=
class=3D"gmail_extra">{</div><div class=3D"gmail_extra">=C2=A0 =C2=A0 std:=
:cout << "A.value =3D " << a.value << std::endl=
; // execute A::access_value() const =C2=A0version</div>
<div class=3D"gmail_extra">}</div><div class=3D"gmail_extra"><br></div><div=
class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">int main()</div=
><div class=3D"gmail_extra">{</div><div class=3D"gmail_extra">=C2=A0 =C2=A0=
A a;</div><div class=3D"gmail_extra">
=C2=A0 =C2=A0 a.value =3D 42; // execute A::access_value() non-const versio=
n returning a reference</div><div class=3D"gmail_extra">=C2=A0 =C2=A0 print=
( a );</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"=
>=C2=A0 =C2=A0 const A& readonly_a =3D a;</div>
<div class=3D"gmail_extra">=C2=A0 =C2=A0 readonly_a.value =3D 123; // ERROR=
: called A::access_value() const version which return a const reference, no=
n modifiable</div><div class=3D"gmail_extra">}</div><div class=3D"gmail_ext=
ra"><br></div>
<div class=3D"gmail_extra">My understanding is that if the expression is ev=
aluated on variable use AND if auto can be used in the inline variable decl=
aration, then the compiler can deduce which version of the function to call=
(const or not const).</div>
<div class=3D"gmail_extra">Am I correct?</div><div class=3D"gmail_extra">Al=
so, is my use of public/private valid here?<br></div><div class=3D"gmail_ex=
tra"><br></div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_ext=
ra"><br>
</div><div class=3D"gmail_extra"><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--089e0111bf72e65f9e04f6989ba5--
.
Author: David Krauss <potswa@gmail.com>
Date: Wed, 9 Apr 2014 17:42:22 +0800
Raw View
--Apple-Mail=_84514FA7-CC2F-4E21-85A4-E78420905DBC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-04-09, at 5:20 PM, Klaim - Jo=EBl Lamotte <mjklaim@gmail.com> wrote=
:
> My understanding is that if the expression is evaluated on variable use A=
ND if auto can be used in the inline variable declaration, then the compile=
r can deduce which version of the function to call (const or not const).
> Am I correct?
I hadn't thought about it, but I don't see why not. I think your logic is s=
ound and the use-case is important. It sounds like a happy confluence. Howe=
ver, it is potentially troublesome to implementations that the placeholder =
type created by auto cannot be resolved until the member access expression =
is formed, with a potentially different result for each qualification of th=
is. I would also want a member-of-rvalue access to produce an rvalue, or ca=
ll an rvalue ref-qualified accessor.
Now I see that the property idiom I mentioned doesn't easily handle such qu=
alification. Your example seems to be superior.
Also, now I see that I forgot to mention the caveat that a pointer-to-membe=
r cannot be formed to an inline member.
> Also, is my use of public/private valid here?
Yes, name binding happens in the declaration context. I want this to be bet=
ter than macros :) .
--=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/.
--Apple-Mail=_84514FA7-CC2F-4E21-85A4-E78420905DBC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;04–09, at 5:20 PM, Klaim - Jo=EBl Lamotte <<a href=3D"mailto=
:mjklaim@gmail.com">mjklaim@gmail.com</a>> wrote:</div><br class=3D"Appl=
e-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div clas=
s=3D"gmail_extra">My understanding is that if the expression is evaluated o=
n variable use AND if auto can be used in the inline variable declaration, =
then the compiler can deduce which version of the function to call (const o=
r not const).</div>
<div class=3D"gmail_extra">Am I correct?</div></div></blockquote><div><br><=
/div><div>I hadn’t thought about it, but I don’t see why not. I=
think your logic is sound and the use-case is important. It sounds like a =
happy confluence. However, it is potentially troublesome to implementations=
that the placeholder type created by <font face=3D"Courier">auto</font> ca=
nnot be resolved until the member access expression is formed, with a poten=
tially different result for each qualification of <font face=3D"Courier">th=
is</font>. I would also want a member-of-rvalue access to produce an rvalue=
, or call an rvalue ref-qualified accessor.</div><div><br></div><div>Now I =
see that the property idiom I mentioned doesn’t easily handle such qu=
alification. Your example seems to be superior.</div><div><br></div><div>Al=
so, now I see that I forgot to mention the caveat that a pointer-to-member =
cannot be formed to an inline member.</div><br><blockquote type=3D"cite"><d=
iv dir=3D"ltr"><div class=3D"gmail_extra">Also, is my use of public/private=
valid here?<br></div></div></blockquote><br></div><div>Yes, name binding h=
appens in the declaration context. I want this to be better than macros :) =
..</div><br></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail=_84514FA7-CC2F-4E21-85A4-E78420905DBC--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 10 Apr 2014 11:28:50 +0200
Raw View
--001a11c35e844e644604f6acd8fa
Content-Type: text/plain; charset=ISO-8859-1
Hi David,
I think you are saying that the declaration-statement inline T x =
initexprand the corresponding id-expression
x are a lot like the declaration statement auto f = [&]{ return
initexpr; }and the corresponding function call expression
f(). Apart from the cosmetic differences, you point out that the inline
variable cannot be assigned. Agreed, but, how does the inline variable
differ from const auto f = [&]{ return initexpr; } ? This also cannot be
assigned.
That is, how does an inline variable differ from a const nullary lambda
object?
Regards,
Andrew.
On Wed, Apr 9, 2014 at 10:17 AM, David Krauss <potswa@gmail.com> wrote:
> Is there an existing proposal along these lines? There was some discussion
> previously in the thread "Variable templates and instantiation -- Is this
> well formed?" around Feb 6.
>
>
> Promote the inline *function-specifier* to a *storage-class-specifier*.
> Like thread_local it may appear with static or extern. Like constexpr it
> causes each declarator to require an initializer. It may appear in a member
> declaration but not a friend declaration. An inline variable does not name
> an object and hence it has no lifetime. It does not reserve any storage.
>
> Evaluation of an inline variable results in evaluation of its initializer.
> The initializer is not evaluated by the declaration. (It is an unevaluated
> context, although that's a confusing way of putting it.) The facility may
> be considered sugar for a nullary lambda object with lambda-capture [&],
> or as a member, for a nullary member function (static or nonstatic
> depending on the static specifier). The effect is like lazy, repeated
> evaluation. However, unlike a lambda object it can only be evaluated, but
> never assigned, so there is no potential expiration of captured references.
>
> Evaluation of an inline variable of reference type produces an lvalue or
> xvalue. Non-reference types produce rvalues, unless the variable is
> declared constexpr, in which case the name is an lvalue referring to
> statically initialized storage. (The linker sees such an object as having
> vague linkage.) This is essentially like adding an implicit lvalue
> reference qualifier to constexpr inline declarations (modulo decltypediscrimination), and the rationale is that there's no benefit to not doing
> so.
>
> An extern constexpr inline variable may safely be ODR-used in multiple
> translation units. Since this is usually how constants are supposed to
> behave, it should be made more convenient and less verbose. The default
> linkage of constexpr inline is therefore external.
>
> The ODR applies to inline variables analogously to inline functions: each
> TU must provide an identical definition, including the inline specifier.
>
> A constexpr inline variable cannot be linked with a non-constexpr
> declaration, no diagnostic required. There is no practical problem with
> allowing this, but neither is there any use case since constexpr inline provides
> a superior alternative, and it would break the uniformity of various rules.
>
> Applications:
> -- Migration of C macros such as stdin from <cstdio>, NULL from <cstddef>,
> and errno from <cerrno>. These could all be contained in std:: with
> deprecation of the macro forms. The macros in the C-style headers (e.g.
> <stdio.h>) would simply fully qualify themselves (e.g. #define stdin
> ::std::stdin).
> -- Tags and constants of class type such as std::piecewise_construct and
> std::allocator_arg. Passing an empty class object of internal linkage by
> value inside an inline function violates the ODR, but passing by reference
> with external linkage (a la std::nothrow) may cause the ABI to require
> use of a parameter slot. Non-empty classes face a similar dilemma regarding
> compile-time value visibility. Even integer constants benefit. Currently
> it's illegal to pass an integer constant through a perfect forwarding
> wrapper from a (multiply-defined) inline function.
> -- Interface string constants, which are similar to constants of class
> type. It becomes much easier use a literally-specified string as a template
> argument in a header, simply constexpr inline char s[] = "blah";. What's
> the next easiest way to accomplish that?
> -- Migration of naked member interfaces to "properties" with getter-setter
> semantics. A member inline variable definition embedding a
> *class-specifier* containing a conversion function and an assignment
> operator serves as an idiomatic property.
> -- Convenient member references, such as to provide named access to a base
> or sibling subobject, or a linked resource, without (de-facto) requiring
> storage. For linked resources or cases where finding the subobject is
> nontrivial, this also avoids potential fancy initialization order footwork.
> -- Named local subexpressions. Although this may currently be done with
> lambdas, an inline variable is more succinct than an inline function.
>
> That's at least six, count-em 6 tough problems solved. The second one may
> really count as two or three. Quite some bang for the buck.
>
> Yes there is some potential for abuse if the expression has side effects,
> but it's still less heinous than the equivalent macro. Anyone who hides
> side effects deserves what they get anyway. If it's really objectionable,
> the specifier can simply be disallowed at local scope with no damage to the
> other use-cases. (Side effects remain possible in declarations at other
> scopes, but the temptation is at local scope.)
>
> As for implementation cost, most of the machinery is already in place in
> the form of lambda functions and variable templates, which capture the
> proposed vague linkage semantics. (Spoiler: this is the above-mentioned
> next easiest way to pass a compile-time string as a template argument, but
> it makes an obtuse idiom.)
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c35e844e644604f6acd8fa
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi David,<div><br></div><div>I think you are saying that t=
he declaration-statement <font face=3D"courier new, monospace">inline =
T x =3D initexpr</font> and the corresponding id-expression <font face=3D"c=
ourier new, monospace">x</font> are a lot like the declaration stateme=
nt <font face=3D"courier new, monospace">auto f =3D [&]{ return initexp=
r; }</font> and the corresponding function call expression <font face=3D"co=
urier new, monospace">f()</font><font face=3D"arial, helvetica, sans-serif"=
>. Apart from the cosmetic differences, you point out that the inline=
variable cannot be assigned. Agreed, but, how does the inline variab=
le differ from </font><font face=3D"courier new, monospace">const auto f =
=3D [&]{ return initexpr; } ?</font><font face=3D"arial, helvetica, san=
s-serif"> This also cannot be assigned.</font></div>
<div><br></div><div>That is, how does an inline variable differ from a cons=
t nullary lambda object?</div><div><br></div><div>Regards,</div><div>Andrew=
..</div><div><br></div><div><font face=3D"arial, helvetica, sans-serif"><br>
</font></div><div><br></div><div><span style=3D"font-family:arial,sans-seri=
f;font-size:13px"><br></span></div></div><div class=3D"gmail_extra"><br><br=
><div class=3D"gmail_quote">On Wed, Apr 9, 2014 at 10:17 AM, David Krauss <=
span dir=3D"ltr"><<a href=3D"mailto:potswa@gmail.com" target=3D"_blank">=
potswa@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word">Is there=
an existing proposal along these lines? There was some discussion previous=
ly in the thread "Variable templates and instantiation -- Is this well=
formed?” around Feb 6.<div>
<br><div><br></div><div>Promote the <font face=3D"Courier">inline</font> <i=
>function-specifier</i> to a <i>storage-class-specifier</i>. Like <font fac=
e=3D"Courier">thread_local</font> it may appear with <font face=3D"Courier"=
>static</font> or <font face=3D"Courier">extern</font>. Like <font face=3D"=
Courier">constexpr</font> it causes each declarator to require an init=
ializer. It may appear in a member declaration but not a friend declaration=
.. An inline variable does not name an object and hence it has no lifetime. =
It does not reserve any storage.</div>
<div><br></div><div>Evaluation of an inline variable results in evaluation =
of its initializer. The initializer is not evaluated by the declaration. (I=
t is an unevaluated context, although that’s a confusing way of putti=
ng it.) The facility may be considered sugar for a nullary lambda object wi=
th lambda-capture <font face=3D"Courier">[&]</font>, or as a member, fo=
r a nullary member function (static or nonstatic depending on the <font fac=
e=3D"Courier">static</font> specifier). The effect is like lazy, repea=
ted evaluation. However, unlike a lambda object it can only be evaluated, b=
ut never assigned, so there is no potential expiration of captured referenc=
es.</div>
<div><br></div><div>Evaluation of an inline variable of reference type prod=
uces an lvalue or xvalue. Non-reference types produce rvalues, unless the v=
ariable is declared <font face=3D"Courier">constexpr</font>, in which case =
the name is an lvalue referring to statically initialized storage. (The lin=
ker sees such an object as having vague linkage.) This is essentially like =
adding an implicit lvalue reference qualifier to <font face=3D"Courier">con=
stexpr inline</font> declarations (modulo <font face=3D"Courier">decltype</=
font> discrimination), and the rationale is that there’s no benefit t=
o not doing so.</div>
<div><br></div><div>An <font face=3D"Courier">extern constexpr inline</font=
> variable may safely be ODR-used in multiple translation units. Since=
this is usually how constants are supposed to behave, it should be made mo=
re convenient and less verbose. The default linkage of <font face=3D"C=
ourier">constexpr inline</font> is therefore external. </div>
<div><br></div><div>The ODR applies to inline variables analogously to inli=
ne functions: each TU must provide an identical definition, including the i=
nline specifier.</div><div><br></div><div>A <font face=3D"Courier">con=
stexpr inline</font> variable cannot be linked with a non-constexpr declara=
tion, no diagnostic required. There is no practical problem with allowing t=
his, but neither is there any use case since<font face=3D"Courier"> co=
nstexpr inline</font> provides a superior alternative, and it wou=
ld break the uniformity of various rules.</div>
<div><br></div><div>Applications:</div></div><div>— Migration of C ma=
cros such as <font face=3D"Courier">stdin</font> from <font face=3D"Courier=
"><cstdio></font>, <font face=3D"Courier">NULL</font> from <font face=
=3D"Courier"><cstddef></font>, and <font face=3D"Courier">errno</font=
> from <font face=3D"Courier"><cerrno></font>. These could =
all be contained in <font face=3D"Courier">std::</font> with deprecation of=
the macro forms. The macros in the C-style headers (e.g. <font face=3D"Cou=
rier"><stdio.h></font>) would simply fully qualify themselves (e.g. <=
font face=3D"Courier">#define stdin ::std::stdin</font>).</div>
<div>— Tags and constants of class type such as <font face=3D"Courier=
">std::piecewise_construct</font> and <font face=3D"Courier">std::allocator=
_arg</font>. Passing an empty class object of internal linkage by value ins=
ide an inline function violates the ODR, but passing by reference with exte=
rnal linkage (a la <font face=3D"Courier">std::nothrow</font>) may cause th=
e ABI to require use of a parameter slot. Non-empty classes face a similar =
dilemma regarding compile-time value visibility. Even integer constants ben=
efit. Currently it’s illegal to pass an integer constant through a pe=
rfect forwarding wrapper from a (multiply-defined) inline function.</div>
<div>— Interface string constants, which are similar to constants of =
class type. It becomes much easier use a literally-specified string as a te=
mplate argument in a header, simply <font face=3D"Courier">constexpr i=
nline char s[] =3D "blah";</font>. What’s the next easiest =
way to accomplish that?</div>
<div>— Migration of naked member interfaces to “properties&rdqu=
o; with getter-setter semantics. A member inline variable definition embedd=
ing a <i>class-specifier</i> containing a conversion function and an assign=
ment operator serves as an idiomatic property.</div>
<div>— Convenient member references, such as to provide named access =
to a base or sibling subobject, or a linked resource, without (de-facto) re=
quiring storage. For linked resources or cases where finding the subobject =
is nontrivial, this also avoids potential fancy initialization order footwo=
rk.</div>
<div>— Named local subexpressions. Although this may currently be don=
e with lambdas, an inline variable is more succinct than an inline function=
..</div><div><br></div><div>That’s at least six, count-em 6 tough prob=
lems solved. The second one may really count as two or three. Quite some ba=
ng for the buck.</div>
<div><br></div><div>Yes there is some potential for abuse if the expression=
has side effects, but it’s still less heinous than the equivalent ma=
cro. Anyone who hides side effects deserves what they get anyway. If it&rsq=
uo;s really objectionable, the specifier can simply be disallowed at local =
scope with no damage to the other use-cases. (Side effects remain possible =
in declarations at other scopes, but the temptation is at local scope.)</di=
v>
<div><br></div><div>As for implementation cost, most of the machinery is al=
ready in place in the form of lambda functions and variable templates, whic=
h capture the proposed vague linkage semantics. (Spoiler: this is the above=
-mentioned next easiest way to pass a compile-time string as a template arg=
ument, but it makes an obtuse idiom.)</div>
<span class=3D"HOEnZb"><font color=3D"#888888"><div><br></div></font></span=
></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--001a11c35e844e644604f6acd8fa--
.
Author: David Krauss <potswa@gmail.com>
Date: Thu, 10 Apr 2014 18:02:14 +0800
Raw View
--Apple-Mail=_B9F55A63-296D-4A2B-BC64-1E584CEBC996
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-04-10, at 5:28 PM, Andrew Tomazos <andrewtomazos@gmail.com> wrote:
> That is, how does an inline variable differ from a const nullary lambda o=
bject?
1. It doesn't need to be called, nor take a user-defined conversion slot. I=
t's a drop-in replacement for things that may be broken, for example a nake=
d member in need of accessors, an inline-unsafe tag like std::piecewise_con=
struct, or the thread-local variable errno which may be incompatible with t=
he thread_local ABI.
2. As a member, it's equivalent to a nullary member function. As Klaim-Jo=
=EBl noticed, with auto it would define a set of member functions. (However=
, now I recall that auto is not allowed as an NSDM type-specifier and I did=
not propose such an allowance.)
3. The lambda object cannot return array type, but the inline object can be=
an array, e.g. initialized by a string literal.
4. A constexpr inline object is an lvalue, potentially with linkage. A cons=
texpr function can only return an rvalue, or a reference to something that =
already existed, but it cannot return a static local.
As a bit of background, I actually arrived at this proposal from the direct=
ion of constexpr and linkage, not lambda functions. At the core this is a p=
roposal to reconcile nonscalar constexpr variables with the ODR. Lambdas (w=
ith their potential side effects) are just a convenient point of reference =
for the value semantics.
--=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/.
--Apple-Mail=_B9F55A63-296D-4A2B-BC64-1E584CEBC996
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;04–10, at 5:28 PM, Andrew Tomazos <<a href=3D"mailto:andrewt=
omazos@gmail.com">andrewtomazos@gmail.com</a>> wrote:</div><br class=3D"=
Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div>=
That is, how does an inline variable differ from a const nullary lambda obj=
ect?</div></div></blockquote><div><br></div><div>1. It doesn’t need t=
o be called, nor take a user-defined conversion slot. It’s a drop-in =
replacement for things that may be broken, for example a naked member in ne=
ed of accessors, an <font face=3D"Courier">inline</font>-unsafe tag like <f=
ont face=3D"Courier">std::piecewise_construct</font>, or the thread-local v=
ariable <font face=3D"Courier">errno</font> which may be incompat=
ible with the <font face=3D"Courier">thread_local</font> ABI.</div><div>2. =
As a member, it’s equivalent to a nullary member function. As Klaim-J=
o=EBl noticed, with <font face=3D"Courier">auto</font> it would define a se=
t of member functions. (However, now I recall that <font face=3D"Courier">a=
uto</font> is not allowed as an NSDM type-specifier and I did not propose s=
uch an allowance.)</div><div>3. The lambda object cannot return array type,=
but the inline object can be an array, e.g. initialized by a string litera=
l.</div><div>4. A constexpr inline object is an lvalue, potentially with li=
nkage. A constexpr function can only return an rvalue, or a reference to so=
mething that already existed, but it cannot return a static local.</div><di=
v><br></div><div>As a bit of background, I actually arrived at this proposa=
l from the direction of <font face=3D"Courier">constexpr</font> and linkage=
, not lambda functions. At the core this is a proposal to reconcile nonscal=
ar <font face=3D"Courier">constexpr</font> variables with the ODR. Lambdas =
(with their potential side effects) are just a convenient point of referenc=
e for the value semantics.</div><div><br></div></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail=_B9F55A63-296D-4A2B-BC64-1E584CEBC996--
.
Author: David Krauss <potswa@gmail.com>
Date: Thu, 10 Apr 2014 18:52:21 +0800
Raw View
--Apple-Mail=_7AF706AA-3076-46A1-8A5E-5BD8BD80F07C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-04-10, at 5:28 PM, Andrew Tomazos <andrewtomazos@gmail.com> wrote:
> That is, how does an inline variable differ from a const nullary lambda o=
bject?
5. The inline variable takes no storage because all the captured references=
are valid through its scope-lifetime. Storage for a capturing lambda objec=
t can only be optimized out with great care. (A constexpr inline object may=
take storage if it is ODR-used, though.)
Also on second thought about linkage, inline should simply cancel the inter=
nal-linkage effect of const; there's nothing so special about constexpr. Th=
e lazy semantic already prevents any dilemma about initialization sequencin=
g, although that question is already resolved by variable templates whose i=
nitialization is completely unsequenced. The inline definition-merging ODR =
behavior already diagnosably ensures that all TUs are getting the same defi=
nition (but no diagnosis required) unless the user specifies static.
--=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/.
--Apple-Mail=_7AF706AA-3076-46A1-8A5E-5BD8BD80F07C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;04–10, at 5:28 PM, Andrew Tomazos <<a href=3D"mailto:andrewt=
omazos@gmail.com">andrewtomazos@gmail.com</a>> wrote:</div><br class=3D"=
Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div>=
That is, how does an inline variable differ from a const nullary lambda obj=
ect?</div></div></blockquote><div><br></div>5. The inline variable takes no=
storage because all the captured references are valid through its scope-li=
fetime. Storage for a capturing lambda object can only be optimized out wit=
h great care. (A constexpr inline object may take storage if it is ODR-used=
, though.)</div><div><br></div><div>Also on second thought about linkage, <=
font face=3D"Courier">inline</font> should simply cancel the internal-linka=
ge effect of <font face=3D"Courier">const</font>; there’s nothing so =
special about <font face=3D"Courier">constexpr</font>. The lazy semantic al=
ready prevents any dilemma about initialization sequencing, although that q=
uestion is already resolved by variable templates whose initialization is c=
ompletely unsequenced. The <font face=3D"Courier">inline</font> defini=
tion-merging ODR behavior already diagnosably ensures that all TUs are gett=
ing the same definition (but no diagnosis required) unless the user specifi=
es <font face=3D"Courier">static</font>.</div><div><br></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail=_7AF706AA-3076-46A1-8A5E-5BD8BD80F07C--
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 10 Apr 2014 16:16:50 +0200
Raw View
--089e0153708849c6d104f6b0de3f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thu, Apr 10, 2014 at 12:02 PM, David Krauss <potswa@gmail.com> wrote:
> 2. As a member, it=E2=80=99s equivalent to a nullary member function. As
> Klaim-Jo=C3=ABl noticed, with auto it would define a set of member functi=
ons.
> (However, now I recall that auto is not allowed as an NSDM type-specifier
> and I did not propose such an allowance.)
>
By the way (about members), I was thinking maybe these would be more
correct:
inline auto&& value =3D access_value(); // would match the return value =
of
the expression?
or
inline decltype(auto) value =3D access_value(); // would match the retur=
n
value of the expression?
But I don't understand fully yet these features so I might be wrong about
the side effects.
--=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/.
--089e0153708849c6d104f6b0de3f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On Thu, Apr 10, 2014 at 12:02 PM, David Krauss <span dir=3D"ltr"><<a hre=
f=3D"mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>></s=
pan> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex"><div>2. As a member, it=E2=80=99s equivalent to a nullary =
member function. As Klaim-Jo=C3=ABl noticed, with <font face=3D"Courier">au=
to</font> it would define a set of member functions. (However, now I recall=
that <font face=3D"Courier">auto</font> is not allowed as an NSDM type-spe=
cifier and I did not propose such an allowance.)</div>
</blockquote></div><br>By the way (about members), I was thinking maybe the=
se would be more correct:</div><div class=3D"gmail_extra"><br></div><div cl=
ass=3D"gmail_extra"><span style=3D"font-family:arial,sans-serif;font-size:1=
2.727272033691406px">=C2=A0=C2=A0 inline auto&& value =3D access_va=
lue(); // would match the return value of the expression?</span><br>
</div><div class=3D"gmail_extra"><span style=3D"font-family:arial,sans-seri=
f;font-size:12.727272033691406px"><br></span></div><div class=3D"gmail_extr=
a"><font face=3D"arial, sans-serif">or</font></div><div class=3D"gmail_extr=
a"><font face=3D"arial, sans-serif"><br>
</font></div><div class=3D"gmail_extra"><span style=3D"font-family:arial,sa=
ns-serif;font-size:12.727272033691406px">=C2=A0=C2=A0 inline decltype(auto)=
</span><span style=3D"font-family:arial,sans-serif;font-size:12.72727203369=
1406px">=C2=A0value =3D access_value();=C2=A0</span><span style=3D"font-fam=
ily:arial,sans-serif;font-size:13px">// would match the return value of the=
expression?</span></div>
<div class=3D"gmail_extra"><span style=3D"font-family:arial,sans-serif;font=
-size:12.727272033691406px"><br></span></div><div class=3D"gmail_extra"><sp=
an style=3D"font-family:arial,sans-serif;font-size:12.727272033691406px">Bu=
t I don't understand fully yet these features so I might be wrong about=
the side effects.</span></div>
</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--089e0153708849c6d104f6b0de3f--
.
Author: Matthias Vegh <matyas.vegh@gmail.com>
Date: Wed, 9 Apr 2014 12:21:08 -0700 (PDT)
Raw View
------=_Part_91_9491438.1397071269419
Content-Type: text/plain; charset=UTF-8
>
> I for one like this idea, as it solves issues like this:
>
void foo(T /*unused*/) {
...
}
T expensive() { ... }
foo(expensive());
expensive() would only be called if someUnlikelyEvent.
However, what if foo is defined in another translation unit?
Unless the signature of foo reflects the fact that is takes an inline
variable (which IIUC would actually be a lambda) the compiler would have no
choice but to call expensive.
What would the signature of foo be that would express the fact (possible
across translation units) that its variable may be unevaluated?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_91_9491438.1397071269419
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D=
"word-wrap:break-word"><div>I for one like this idea, as it solves issues l=
ike this:<br></div></div></blockquote><div><br></div><div>void foo(T /*unus=
ed*/) {</div><div> ...<br>}</div><div><br></div><div>T expensi=
ve() { ... }</div><div><br></div><div>foo(expensive());</div><div><br></div=
><div>expensive() would only be called if someUnlikelyEvent.</div><div><br>=
</div><div>However, what if foo is defined in another translation unit?</di=
v><div>Unless the signature of foo reflects the fact that is takes an inlin=
e variable (which IIUC would actually be a lambda) the compiler would have =
no choice but to call expensive.</div><div><br></div><div>What would the si=
gnature of foo be that would express the fact (possible across translation =
units) that its variable may be unevaluated?</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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_91_9491438.1397071269419--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 12 Apr 2014 11:47:10 +0800
Raw View
--Apple-Mail=_89BD9308-CC35-4DFD-8A5E-5FEAADB170DB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-04-10, at 3:21 AM, Matthias Vegh <matyas.vegh@gmail.com> wrote:
> However, what if foo is defined in another translation unit?
> Unless the signature of foo reflects the fact that is takes an inline var=
iable (which IIUC would actually be a lambda) the compiler would have no ch=
oice but to call expensive.
Evaluation of an inline variable, i.e. simply naming it in an evaluated con=
text, results in evaluation of its initializer. The laziness only cancels e=
valuation at the declaration, same as evaluation of a lambda-expression doe=
s not execute its compound-statement.
An inline variable is not "actually" a lambda and perhaps I shouldn't have =
suggested that, although the evaluation semantics are the same. The linkage=
is different.
> What would the signature of foo be that would express the fact (possible =
across translation units) that its variable may be unevaluated?
I'm avoiding such a feature, because it would not be compatible with curren=
t compiler architectures. inline like most other storage-class-specifiers c=
annot be applied to a parameter. Compilers can already skip a complex calcu=
lation with an unused result through inlining, although it has to be sure n=
o side effects get elided.
--=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/.
--Apple-Mail=_89BD9308-CC35-4DFD-8A5E-5FEAADB170DB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"text/html cha=
rset=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"text/html=
charset=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webk=
it-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>=
On 2014–04–10, at 3:21 AM, Matthias Vegh <<a href=3D"mailto:=
matyas.vegh@gmail.com">matyas.vegh@gmail.com</a>> wrote:</div><div><br><=
/div><blockquote type=3D"cite"><div dir=3D"ltr">However, what if foo is def=
ined in another translation unit?</div></blockquote><blockquote type=3D"cit=
e"><div dir=3D"ltr">Unless the signature of foo reflects the fact that is t=
akes an inline variable (which IIUC would actually be a lambda) the compile=
r would have no choice but to call expensive.</div></blockquote><div><br></=
div>Evaluation of an inline variable, i.e. simply naming it in an evaluated=
context, results in evaluation of its initializer. The laziness only cance=
ls evaluation at the declaration, same as evaluation of a lambda-expression=
does not execute its compound-statement.</div><div><br></div><div>An inlin=
e variable is not “actually” a lambda and perhaps I shouldn&rsq=
uo;t have suggested that, although the evaluation semantics are the same. T=
he linkage is different.</div><div><br><blockquote type=3D"cite"><div dir=
=3D"ltr">What would the signature of foo be that would express the fact (po=
ssible across translation units) that its variable may be unevaluated?</div=
></blockquote><br></div><div>I’m avoiding such a feature, because it =
would not be compatible with current compiler architectures. <font face=3D"=
Courier">inline</font> like most other storage-class-specifiers cannot be a=
pplied to a parameter. Compilers can already skip a complex calculation wit=
h an unused result through inlining, although it has to be sure no side eff=
ects get elided.</div><br></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail=_89BD9308-CC35-4DFD-8A5E-5FEAADB170DB--
.
Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Sat, 12 Apr 2014 10:04:52 +0200
Raw View
--Apple-Mail-1A1B092E-BE43-46E2-B998-A0CD3DD18B74
Content-Type: text/plain; charset=ISO-8859-1
Il giorno 09/apr/2014, alle ore 21:21, Matthias Vegh <matyas.vegh@gmail.com> ha scritto:
>> I for one like this idea, as it solves issues like this:
>
> void foo(T /*unused*/) {
> ...
> }
>
> T expensive() { ... }
>
> foo(expensive());
>
> expensive() would only be called if someUnlikelyEvent.
>
> However, what if foo is defined in another translation unit?
> Unless the signature of foo reflects the fact that is takes an inline variable (which IIUC would actually be a lambda) the compiler would have no choice but to call expensive.
>
> What would the signature of foo be that would express the fact (possible across translation units) that its variable may be unevaluated?
That is what I've suggested (not that I was the first) some time ago in another thread. Basically it's lazy evaluation of parameters. With an additional qualifier you can do:
void foo(lazy T arg) {
}
And the compiler generates a function that accept a lambda. At the call site, the argument expression is automatically wrapped in such a lambda. The problem is with side effects,
but in my opinion the problems are solvable and the advantages are worth the pain.
Bye,
Nicola
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--Apple-Mail-1A1B092E-BE43-46E2-B998-A0CD3DD18B74
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div>Il giorno 09/apr/2014, alle ore 21=
:21, Matthias Vegh <<a href=3D"mailto:matyas.vegh@gmail.com">matyas.vegh=
@gmail.com</a>> ha scritto:</div><div><br></div><blockquote type=3D"cite=
"><div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div s=
tyle=3D"word-wrap:break-word"><div>I for one like this idea, as it solves i=
ssues like this:<br></div></div></blockquote><div><br></div><div>void foo(T=
/*unused*/) {</div><div> ...<br>}</div><div><br></div><div>T =
expensive() { ... }</div><div><br></div><div>foo(expensive());</div><div><b=
r></div><div>expensive() would only be called if someUnlikelyEvent.</div><d=
iv><br></div><div>However, what if foo is defined in another translation un=
it?</div><div>Unless the signature of foo reflects the fact that is takes a=
n inline variable (which IIUC would actually be a lambda) the compiler woul=
d have no choice but to call expensive.</div><div><br></div><div>What would=
the signature of foo be that would express the fact (possible across trans=
lation units) that its variable may be unevaluated?</div></div></div></bloc=
kquote><div><br></div><div>That is what I've suggested (not that I was the =
first) some time ago in another thread. Basically it's lazy evaluation of p=
arameters. With an additional qualifier you can do:</div><div><br></div><di=
v>void foo(lazy T arg) {</div><div><br></div><div>}</div><div><br></div><di=
v>And the compiler generates a function that accept a lambda. At the call s=
ite, the argument expression is automatically wrapped in such a lambda. The=
problem is with side effects,</div><div>but in my opinion the problems are=
solvable and the advantages are worth the pain.</div><br><div>Bye,</div><d=
iv>Nicola</div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail-1A1B092E-BE43-46E2-B998-A0CD3DD18B74--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 13 Apr 2014 12:42:50 +0800
Raw View
--Apple-Mail=_7BC38B3D-1903-4C09-885B-3CDC360575E8
Content-Type: text/plain; charset=ISO-8859-1
On 2014-04-12, at 4:04 PM, Nicola Gigante <nicola.gigante@gmail.com> wrote:
> void foo(lazy T arg) {
>
> }
>
> And the compiler generates a function that accept a lambda.
This wouldn't work with linkage. My impression from the other thread was that you wanted to pass a dispatching functor, such as std::function.
> The problem is with side effects,
> but in my opinion the problems are solvable and the advantages are worth the pain.
The other problem is the variety of means to the end, that one size won't fit all, and it may be hard for the user to keep track of the underlying mechanism if it automatically selects between polymorphic wrappers and lambdas, caching or not, etc.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--Apple-Mail=_7BC38B3D-1903-4C09-885B-3CDC360575E8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;04–12, at 4:04 PM, Nicola Gigante <<a href=3D"mailto:nicola.=
gigante@gmail.com">nicola.gigante@gmail.com</a>> wrote:</div><br class=
=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"auto" =
style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font-=
variant: normal; font-weight: normal; letter-spacing: normal; line-height: =
normal; orphans: auto; text-align: start; text-indent: 0px; text-transform:=
none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-s=
troke-width: 0px;"><div>void foo(lazy T arg) {</div><div><br></div><div>}</=
div><div><br></div><div>And the compiler generates a function that accept a=
lambda. </div></div></blockquote><div><br></div><div>This wouldn’t w=
ork with linkage. My impression from the other thread was that you wanted t=
o pass a dispatching functor, such as <font face=3D"Courier">std::func=
tion</font>.</div></div><br><div><blockquote type=3D"cite"><div>The problem=
is with side effects,</div><div>but in my opinion the problems are solvabl=
e and the advantages are worth the pain.</div></blockquote><br></div><div>T=
he other problem is the variety of means to the end, that one size won&rsqu=
o;t fit all, and it may be hard for the user to keep track of the underlyin=
g mechanism if it automatically selects between polymorphic wrappers and la=
mbdas, caching or not, etc.</div><div><br></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail=_7BC38B3D-1903-4C09-885B-3CDC360575E8--
.
Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Sun, 13 Apr 2014 11:57:37 +0200
Raw View
--Apple-Mail-7EEC7A9B-1224-4362-8C4B-4F786FE83ED2
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Il giorno 13/apr/2014, alle ore 06:42, David Krauss <potswa@gmail.com> ha s=
critto:
>=20
>=20
>> On 2014=E2=80=9304=E2=80=9312, at 4:04 PM, Nicola Gigante <nicola.gigant=
e@gmail.com> wrote:
>>=20
>> void foo(lazy T arg) {
>>=20
>> }
>>=20
>> And the compiler generates a function that accept a lambda.
>=20
> This wouldn=E2=80=99t work with linkage. My impression from the other thr=
ead was that you wanted to pass a dispatching functor, such as std::functio=
n.
>=20
The underlying mechanics would be implementation-dependent, but yes. We see=
an additional dispatch step as a slowdown compared to raw lambdas, but it'=
s how it works in all other languages after all.. Or you could imagine a se=
mantics where you can use those qualifiers only in a template, so you can t=
empletize the type and pass a real lambda. Or it could work both ways depen=
ding on if it's a template or not.
>> The problem is with side effects,
>> but in my opinion the problems are solvable and the advantages are worth=
the pain.
>=20
> The other problem is the variety of means to the end, that one size won=
=E2=80=99t fit all, and it may be hard for the user to keep track of the un=
derlying mechanism if it automatically selects between polymorphic wrappers=
and lambdas, caching or not, etc.
>=20
It should be as transparent as possible. Besides mangling issues, the user =
should see no difference between different implementation techniques. And I=
don't think the user should worry about caching neither. IMHO the right ap=
proach is to demand that the side effects of the argument expression have t=
o be executed at most once if at all, and it of course means the first time=
the function body evaluates the parameter.=20
And especially in function templates, where at instantiation time the compi=
ler will have the most freedom, all this can be optimized very well.=20
Regards,
Nicola
--=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/.
--Apple-Mail-7EEC7A9B-1224-4362-8C4B-4F786FE83ED2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div>Il giorno 13/apr/2014, alle ore 06=
:42, David Krauss <<a href=3D"mailto:potswa@gmail.com">potswa@gmail.com<=
/a>> ha scritto:</div><div><br></div><blockquote type=3D"cite"><div><met=
a http-equiv=3D"Content-Type" content=3D"text/html charset=3Dwindows-1252">=
<br><div><div>On 2014=E2=80=9304=E2=80=9312, at 4:04 PM, Nicola Gigante <=
;<a href=3D"mailto:nicola.gigante@gmail.com">nicola.gigante@gmail.com</a>&g=
t; wrote:</div><br class=3D"Apple-interchange-newline"><blockquote type=3D"=
cite"><div dir=3D"auto" style=3D"font-family: Helvetica; font-size: 12px; f=
ont-style: normal; font-variant: normal; font-weight: normal; letter-spacin=
g: normal; line-height: normal; orphans: auto; text-align: start; text-inde=
nt: 0px; text-transform: none; white-space: normal; widows: auto; word-spac=
ing: 0px; -webkit-text-stroke-width: 0px;"><div>void foo(lazy T arg) {</div=
><div><br></div><div>}</div><div><br></div><div>And the compiler generates =
a function that accept a lambda. </div></div></blockquote><div><br></div><d=
iv>This wouldn=E2=80=99t work with linkage. My impression from the other th=
read was that you wanted to pass a dispatching functor, such as <font =
face=3D"Courier">std::function</font>.</div></div><br></div></blockquote><d=
iv><br></div><div>The underlying mechanics would be implementation-dependen=
t, but yes. We see an additional dispatch step as a slowdown compared to ra=
w lambdas, but it's how it works in all other languages after all.. Or you =
could imagine a semantics where you can use those qualifiers only in a temp=
late, so you can templetize the type and pass a real lambda. Or it could wo=
rk both ways depending on if it's a template or not.</div><br><blockquote t=
ype=3D"cite"><div><div><blockquote type=3D"cite"><div>The problem is with s=
ide effects,</div><div>but in my opinion the problems are solvable and the =
advantages are worth the pain.</div></blockquote><br></div><div>The other p=
roblem is the variety of means to the end, that one size won=E2=80=99t fit =
all, and it may be hard for the user to keep track of the underlying mechan=
ism if it automatically selects between polymorphic wrappers and lambdas, c=
aching or not, etc.</div><div><br></div></div></blockquote><div><br></div><=
div>It should be as transparent as possible. Besides mangling issues, the u=
ser should see no difference between different implementation techniques. A=
nd I don't think the user should worry about caching neither. IMHO the righ=
t approach is to demand that the side effects of the argument expression ha=
ve to be executed at most once if at all, and it of course means the first =
time the function body evaluates the parameter. </div><div><br></div><=
div>And especially in function templates, where at instantiation time the c=
ompiler will have the most freedom, all this can be optimized very well.&nb=
sp;</div><div><br></div>Regards,<div>Nicola<br><blockquote type=3D"cite"><d=
iv>
<p></p>
</div></blockquote></div><div><br></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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 />
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 />
--Apple-Mail-7EEC7A9B-1224-4362-8C4B-4F786FE83ED2--
.