Вложенные лямбда-захваты - PullRequest
5 голосов
/ 05 июля 2011

Когда я обращаюсь к переменной a внутри "run" lambda, я вижу, что адрес отличается от 'a' в main.Это происходит только с такого рода лямбда-вложения.Этого следовало ожидать?Я могу воспроизводить только с таким нетривиальным вложением.

Я проверяю адрес с помощью gdb внутри лямбды, как это -> __a

Печать внутри лямбды с помощью gdb дает мусор, в то время каклямбда имеет захваченные параметры внутри лямбда-объекта, поэтому меня удивляет, что этот -> __a имеет адрес, отличный от a:

(gdb) p &a
$5 = (unsigned int *) 0x7fffffffdce8
(gdb) p *this
$6 = {__a = @0x7fffffffdde8}
(gdb) p a
$7 = 4207233
(gdb) p this->__a
$8 = (unsigned int &) @0x7fffffffdde8: 2

Когда лямбда не является вложенной, я вспоминаю, как наблюдал тот же адрес.

В настоящее время наблюдается такое поведение в g ++ - 4.5 (Debian 4.5.3-3) 4.5.3 и g ++ - 4.6 (Debian 4.6.0-10) 4.6.1 20110526 (предварительная версия)

#include <string>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <stdexcept>
#include <stdint.h>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
    unsigned a = 0;
    vector<int> vi = {0, 1, 2, 3, 4 };

    auto run = [&](int& i) {
        // inside this lambda &a is not the same as the &a in the first line
        cout << "i: " << i << endl;
        a++;
        cout << "a: " << a << endl;

    };
    for_each(vi.begin(), vi.end(), [&](int& xi) {
        run(xi);
    });

    cout << "a: " << a << endl;
}

Я заполнил следующий отчет об ошибке, связанный с этим вопросом: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49651

Ответы [ 2 ]

1 голос
/ 29 декабря 2012

Это была ошибка в gcc.Это исправлено.

См. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49651

0 голосов
/ 05 октября 2011

Это простой силлогизм:

  • Печать &a дает правильное значение.
  • Наблюдение this->__a дает другое значение.

1011 * эрго *

  • this->__a не то же самое, что &a

Так как мы можем это объяснить? this->__a может быть объектом, который содержит описание из a, компилятор может поместить туда любые метаданные для отладки или любых других целей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...