According to the answers and comments for this question, when a reference variable is captured by value, the lambda object should make a copy of the referenced object, not the reference itself. However, GCC doesn't seem to do this.
Using the following test:
#include <stddef.h> #include <iostream> using std::cout; using std::endl; int main(int argc, char** argv) { int i = 10; int& ir = i; [=] { cout << "value capture" << endl << "i: " << i << endl << "ir: " << ir << endl << "&i: " << &i << endl << "&ir: " << &ir << endl << endl; }(); [&] { cout << "reference capture" << endl << "i: " << i << endl << "ir: " << ir << endl << "&i: " << &i << endl << "&ir: " << &ir << endl << endl; }(); return EXIT_SUCCESS; }
Compiling with GCC 4.5.1, using -std=c++0x
, and running gives the following output:
value capture i: 10 ir: -226727748 &i: 0x7ffff27c68a0 &ir: 0x7ffff27c68a4 reference capture i: 10 ir: 10 &i: 0x7ffff27c68bc &ir: 0x7ffff27c68bc
When captured by copy, ir
just references junk data. But it correctly references i
when captured by reference.
Is this a bug in GCC? If so, does anyone know if a later version fixes it? What is the correct behavior?
If the first lambda function is changed to
[i, ir] { cout << "explicit value capture" << endl << "i: " << i << endl << "ir: " << ir << endl << "&i: " << &i << endl << "&ir: " << &ir << endl << endl; }();
then the output looks correct:
explicit value capture i: 10 ir: 10 &i: 0x7fff0a5b5790 &ir: 0x7fff0a5b5794
This looks more and more like a bug.
The mutable keyword is used so that the body of the lambda expression can modify its copies of the external variables x and y , which the lambda expression captures by value. Because the lambda expression captures the original variables x and y by value, their values remain 1 after the lambda executes.
The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.
A reference variable is a variable that points to an object of a given class, letting you access the value of an object. An object is a compound data structure that holds values that you can manipulate. A reference variable does not store its own values.
A reference is defined as an alias for another variable. In short, it is like giving a different name to a pre-existing variable. Once a reference is initialized to the variable, we can use either the reference name or the variable to refer to that variable.
This has just been fixed in gcc-4.7 trunk and gcc-4.6 branch. These should be available in gcc-4.7.0 (a while from now - still in stage 1) and gcc-4.6.2 (alas 4.6.1 just came out.)
But the intrepid could wait for the next snapshots or get a subversion copy.
See audit trail for details.
Compiled with VS 2010 gives:
value capture i: 10 ir: 10 &i: 0012FE74 &ir: 0012FE78 reference capture i: 10 ir: 10 &i: 0012FF60 &ir: 0012FF60
Looks like a bug for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With