Pertanyaan Menangkap variabel referensi dengan menyalin di C ++ 0x lambda


Menurut jawaban dan komentar untuk pertanyaan ini, ketika sebuah variabel referensi ditangkap oleh nilai, objek lambda harus membuat salinan objek yang direferensikan, bukan referensi itu sendiri. Namun, GCC tampaknya tidak melakukan ini.

Menggunakan tes berikut:

#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;
}

Kompilasi dengan GCC 4.5.1, menggunakan -std=c++0x, dan berjalan memberi keluaran berikut:

value capture
i: 10
ir: -226727748
&i: 0x7ffff27c68a0
&ir: 0x7ffff27c68a4

reference capture
i: 10
ir: 10
&i: 0x7ffff27c68bc
&ir: 0x7ffff27c68bc

Ketika ditangkap oleh salinan, ir hanya referensi data sampah. Tapi itu benar referensi i ketika diambil dengan referensi.

Apakah ini bug di GCC? Jika demikian, apakah ada yang tahu jika versi yang lebih baru memperbaikinya? Apa perilaku yang benar?

EDIT

Jika fungsi lambda pertama diubah menjadi

[i, ir]
{
    cout << "explicit value capture" << endl
         << "i: " << i << endl
         << "ir: " << ir << endl
         << "&i: " << &i << endl
         << "&ir: " << &ir << endl
         << endl;
}();

maka hasilnya terlihat benar:

explicit value capture
i: 10
ir: 10
&i: 0x7fff0a5b5790
&ir: 0x7fff0a5b5794

Ini terlihat seperti bug.


32
2018-06-30 01:50


asal


Jawaban:


Ini baru saja diperbaiki di gcc-4.7 trunk dan gcc-4.6 branch. Ini harus tersedia di gcc-4.7.0 (sementara dari sekarang - masih dalam tahap 1) dan gcc-4.6.2 (sayangnya 4.6.1 baru saja keluar.)

Tapi pemberani bisa menunggu snapshot berikutnya atau mendapatkan salinan subversi.

Lihat jejak audit untuk detailnya.


7
2017-07-05 19:37



Dikompilasi dengan VS 2010 memberikan:

pengambilan nilai
i: 10
ir: 10
& i: 0012FE74
& ir: 0012FE78

pengambilan referensi
i: 10
ir: 10
& i: 0012FF60
& ir: 0012FF60

Terlihat seperti bug untukku.


4
2018-06-30 02:40