Topic: C++0x: why is capturing (w.r.t. lambdas) restricted to auto variables?
Author: SG <s.gesemann@gmail.com>
Date: Tue, 15 Mar 2011 10:36:38 CST Raw View
Hi!
I just checked 5.1.2/7-10 [expr.prim.lambda] and noticed something
that looks like an unnecessary restriction to me:
N3225.pdf, 5.1.2/10:
"The identifiers in a capture-list are looked up using the usual
rules for unqualified name lookup (3.4.1); each such lookup
shall find a variable with automatic storage duration declared
in the reaching scope of the local lambda expression. An entity
(i.e. a variable or this) is said to be explicitly captured if
it appears in the lambda-expression s capture-list."
Apparently, the following code
struct S1 {
int x;
void f() {
[x]() mutable ->int {
++x;
return x;
}();
}
};
violates 5.1.2/10 because 'x' is not (necessarily) a variable with
automatic storage duraction. If so, what is the reason for this
restriction? Why am I forced to write
struct S1 {
int x;
void f() {
int dummy = x;
[dummy]() mutable ->int {
++dummy;
return dummy;
}();
}
};
?
FWIW, GCC compiles the first example and behaves like I expected it
to. To allow this behaviour in the upcoming C++ standard, 5.1.2/7
seems to require a rewording as well:
N3225.pdf, 5.1.2/7:
"The lambda-expression s compound-statement yields the function-
body (8.4) of the function call operator, but for purposes of name
lookup (3.4), determining the type and value of this (9.3.2) and
transforming idexpressions referring to non-static class members
into class member access expressions using (*this) (9.3.1), the
compound-statement is considered in the context of the lambda-
expression. [...]"
Apparently, in the first code example, GCC did not transform 'x' to be
'(*this).x' but rather created a copy of x inside the lambda object. I
actually like the possibility of explicitly capturing non-static data
members by copy and IMHO it should be supported without ugly work-
arounds like creating extra local copies.
Comments?
Cheers!
SG
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: SG <s.gesemann@gmail.com>
Date: Tue, 29 Mar 2011 13:10:15 CST Raw View
In case it wasn't clear what I was asking about two weeks ago, here is
a rewording including two other examples:
On 15 Mrz., 18:36, SG wrote:
>
> I just checked 5.1.2/7-10 [expr.prim.lambda] and noticed something
> that looks like an unnecessary restriction to me:
>
> N3225.pdf, 5.1.2/10:
> "The identifiers in a capture-list are looked up using the usual
> rules for unqualified name lookup (3.4.1); each such lookup
> shall find a variable with automatic storage duration declared
> in the reaching scope of the local lambda expression. An entity
> (i.e. a variable or this) is said to be explicitly captured if
> it appears in the lambda-expression=92s capture-list."
>
> Apparently, the following code
>
> struct S1 {
> int x;
> void f() {
> [x]() mutable ->int {
> ++x;
> return x;
> }();
> }
> };
>
> violates 5.1.2/10 because 'x' is not (necessarily) a variable with
> automatic storage duraction.
Another example would be
int global = 0;
int main() {
[global]{return global;}();
}
Basically, I would appreciate someone explaining whether the above
examples are supposed to work or not. It is my interpretation that
they are not supposed to work. Please confirm or correct me if I'm
wrong.
Another aspect is: What happends w.r.t. capturing local references?
int main() {
int i = 0;
int& r = i;
bool question = [r]{return &r;}() == &i;
}
Does the lambda object store "a copy of a reference" or "a copy of an
int"? I could not find anything conclusive in the current draft. GCC
seems to copy the int (which is a desirable behaviour, IMHO).
Thanks in advance!
SG
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?windows-1252?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 30 Mar 2011 13:06:05 CST Raw View
Am 29.03.2011 21:10, schrieb SG:
>
> In case it wasn't clear what I was asking about two weeks ago, here is
> a rewording including two other examples:
I guess that there was no response yet, because of the Madrid meeting
(including preparation time for this event).
> On 15 Mrz., 18:36, SG wrote:
>>
>> I just checked 5.1.2/7-10 [expr.prim.lambda] and noticed something
>> that looks like an unnecessary restriction to me:
>>
>> N3225.pdf, 5.1.2/10:
>> "The identifiers in a capture-list are looked up using the usual
>> rules for unqualified name lookup (3.4.1); each such lookup
>> shall find a variable with automatic storage duration declared
>> in the reaching scope of the local lambda expression. An entity
>> (i.e. a variable or this) is said to be explicitly captured if
>> it appears in the lambda-expression=92s capture-list."
>>
>> Apparently, the following code
>>
>> struct S1 {
>> int x;
>> void f() {
>> [x]() mutable ->int {
>> ++x;
>> return x;
>> }();
>> }
>> };
>>
>> violates 5.1.2/10 because 'x' is not (necessarily) a variable with
>> automatic storage duraction.
Yes, this fact has already been observed by others, e.g. by Dave
Abrahams around June 2010 elsewhere and by Helmut Jarausch (End of
February this year) on c.l.c.mod.
> Another example would be
>
> int global = 0;
> int main() {
> [global]{return global;}();
> }
>
> Basically, I would appreciate someone explaining whether the above
> examples are supposed to work or not. It is my interpretation that
> they are not supposed to work. Please confirm or correct me if I'm
> wrong.
Your interpretation is correct. The committee decided intentionally to
limit the possibilities of captures in this first release of lambdas
in C++. It looks quite reasonably to allow for (explicit) capturing
non-automatic variables in the future as well. The original lambda
proposal also allowed for capturing expressions, but that was
considered as going too far for this initial release.
> Another aspect is: What happends w.r.t. capturing local references?
>
> int main() {
> int i = 0;
> int& r = i;
> bool question = [r]{return&r;}() ==&i;
> }
>
> Does the lambda object store "a copy of a reference" or "a copy of an
> int"? I could not find anything conclusive in the current draft. GCC
> seems to copy the int (which is a desirable behaviour, IMHO).
There does not exist the concept of a "copy of a reference". IMO the
wording in p. 14 clearly says that the referenced object is copied in
this case:
"The type of such a data member is the type of the corresponding
captured entity if the entity is not a reference to an object, or the
referenced type otherwise."
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Johannes Schaub (litb)" <schaub.johannes@googlemail.com>
Date: Wed, 30 Mar 2011 13:05:17 CST Raw View
SG wrote:
[...]
> Another aspect is: What happends w.r.t. capturing local references?
>
> int main() {
> int i = 0;
> int& r = i;
> bool question = [r]{return &r;}() == &i;
> }
>
> Does the lambda object store "a copy of a reference" or "a copy of an
> int"? I could not find anything conclusive in the current draft. GCC
> seems to copy the int (which is a desirable behaviour, IMHO).
>
n3242 says in 5.1.2p14:
"The type of such a data member is the type of the corresponding captured
entity if the entity is not a reference to an object, or the referenced type
otherwise."
Which means that the closure contains an int, not a reference to it.
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]