Kode berikut terlihat agak tidak berbahaya pada pandangan pertama. Seorang pengguna menggunakan fungsi bar()
untuk berinteraksi dengan beberapa fungsi perpustakaan. (Ini mungkin telah bekerja untuk waktu yang lama sejak bar()
mengembalikan referensi ke nilai non-temporer atau serupa.) Namun sekarang hanya mengembalikan contoh baru B
. B
lagi memiliki fungsi a()
yang mengembalikan referensi ke objek dengan tipe iterateable A
. Pengguna ingin menanyakan objek ini yang mengarah ke segfault karena B
objek sementara yang dikembalikan oleh bar()
dihancurkan sebelum iterasi dimulai.
Saya ragu siapa (perpustakaan atau pengguna) yang harus disalahkan untuk ini. Semua kelas yang disediakan perpustakaan terlihat bersih bagi saya dan tentu saja tidak melakukan hal yang berbeda (mengembalikan referensi ke anggota, mengembalikan instance stack, ...) daripada begitu banyak kode lain di luar sana. Pengguna tampaknya tidak melakukan sesuatu yang salah juga, ia hanya mengulangi beberapa objek tanpa melakukan apa-apa mengenai objek itu seumur hidup.
(Pertanyaan terkait mungkin: Haruskah seseorang menetapkan aturan umum bahwa kode tidak boleh "rentang-berdasarkan-untuk-iterate" atas sesuatu yang diambil oleh lebih dari satu panggilan berantai di header loop karena salah satu dari panggilan ini dapat mengembalikan menilai kembali?)
#include <algorithm>
#include <iostream>
// "Library code"
struct A
{
A():
v{0,1,2}
{
std::cout << "A()" << std::endl;
}
~A()
{
std::cout << "~A()" << std::endl;
}
int * begin()
{
return &v[0];
}
int * end()
{
return &v[3];
}
int v[3];
};
struct B
{
A m_a;
A & a()
{
return m_a;
}
};
B bar()
{
return B();
}
// User code
int main()
{
for( auto i : bar().a() )
{
std::cout << i << std::endl;
}
}