Segfault при захвате этого в классе шаблона - PullRequest
0 голосов
/ 23 сентября 2018

При изучении функций C ++ 11 я заметил, что этот код падает с segfault:

#include <iostream>
#include <functional>

using namespace std;

template <int X = 42>
struct Test {
    int x = X;
    void printer() {
        cout << "this value: " << x <<  endl;
    }
    std::function<void()> lambda = [this] {printer();};
};


int main()
{
    Test<> t;
    t.lambda();
    return 0;
}

Если я сделаю Test обычной структурой вместо шаблона, она будет работать.Это почему?ОС: Ubuntu 16.04, компилятор: g ++ 6.3

Редактировать: Работает на Clang.Должно быть ошибка в G ++.

1 Ответ

0 голосов
/ 23 сентября 2018

Я провел эксперимент, он работает с g ++ 8.1 и падает с segfault на g ++ 7.3.С помощью трассировки gdb обнаруживается, что при возникновении ошибки указатель this, захваченный лямбда-выражением, равен нулю, что связано со стратегией компилятора по инициализации лямбда-переменной (указатель this еще не инициализирован, когда компиляторинициализирует лямбду).Это может работать, помещая инициализацию в список инициализации конструктора:

#include <iostream>
#include <functional>

using namespace std;

template <int X = 42>
struct Test {
    int x = X;
    void printer() {
        cout << "this value: " << x <<  endl;
    }
    std::function<void()> lambda;
    Test():lambda([this] {printer();}){}
};


int main()
{
    Test<> t;
    t.lambda();
    return 0;
}
...