Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing reference variable by copy in C++0x lambda

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?

EDIT

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.

like image 272
jakar Avatar asked Jun 30 '11 01:06

jakar


People also ask

Does Lambda capture reference by value?

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.

What does it mean to Lambda capture this?

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.

What is refernce variable?

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.

What is a reference to a variable in C?

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.


2 Answers

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.

like image 58
emsr Avatar answered Sep 20 '22 19:09

emsr


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.

like image 33
Sasha Avatar answered Sep 20 '22 19:09

Sasha