C++:
template <class _Func> void for_each_entity(_Func & func)
{
itertype(m_set_entity) it = m_set_entity.begin();
for ( ; it != m_set_entity.end(); ++it) {
LPENTITY entity = *it;
// <Factor> Sanity check
if (entity->GetSectree() != this) {
sys_err("<Factor> SECTREE-ENTITY relationship mismatch");
m_set_entity.erase(it);
continue;
}
func(entity);
}
}
Bu kodda UB var;
it erase edilip continue statement yazılmış. erase(it) sadece silinen elemana ait iterator'ı invalidate eder, statementda loop invalidate edilmiş iteratörü increment ediyor, olması gereken "it = m_set_entity.erase(it)" yazıp for yerine while döngüsüne çevirmek (erase zaten bir sonraki geçerli iterator'ı döndürüyor). Neyse, biraz daha inceleyip özetle C++20 için şöyle bir çözüm üretebilirsiniz;
C++:
template <class _Func> void for_each_entity(_Func & func)
{
std::erase_if(m_set_entity, [this](LPENTITY entity) {
if (entity->GetSectree() != this) {
sys_err("<Factor> SECTREE-ENTITY relationship mismatch");
return true;
}
return false;
});
std::ranges::for_each(m_set_entity, std::ref(func));
}
UB ise neden bugüne kadar patlamadı derseniz adı üstünde UB ne olacağını ancak Allah bilebilir, kimse öngöremez teknik detay için compiler dökümanlarına bakmak lazım.
En Çok Reaksiyon Alan Mesajlar
UB’nin bugüne kadar fark edilmemesinin asıl nedeni sanırım, yalnızca entity->GetSectree() != this tutarsızlığı oluştuğunda tetiklenmesidir. Normal InsertEntity/RemoveEntity akışı bu ilişkiyi tutarlı tuttuğundan sorunlu dal muhtemelen hiç veya çok nadir çalışıyor; çalıştığında da silinen düğümün belleği hemen bozulmadığı için kod şans eseri devam edebiliyor.C++:template <class _Func> void for_each_entity(_Func & func) { itertype(m_set_entity) it = m_set_entity.begin(); for ( ; it != m_set_entity.end(); ++it) { LPENTITY entity = *it; // <Factor> Sanity check if (entity->GetSectree() != this) { sys_err("<Factor> SECTREE-ENTITY relationship mismatch"); m_set_entity.erase(it); continue; } func(entity); } }
Bu kodda UB var;
it erase edilip continue statement yazılmış. erase(it) sadece silinen elemana ait iterator'ı invalidate eder, statementda loop invalidate edilmiş iteratörü increment ediyor, olması gereken "it = m_set_entity.erase(it)" yazıp for yerine while döngüsüne çevirmek (erase zaten bir sonraki geçerli iterator'ı döndürüyor). Neyse, biraz daha inceleyip özetle C++20 için şöyle bir çözüm üretebilirsiniz;
C++:template <class _Func> void for_each_entity(_Func & func) { std::erase_if(m_set_entity, [this](LPENTITY entity) { if (entity->GetSectree() != this) { sys_err("<Factor> SECTREE-ENTITY relationship mismatch"); return true; } return false; }); std::ranges::for_each(m_set_entity, std::ref(func)); }
UB ise neden bugüne kadar patlamadı derseniz adı üstünde UB ne olacağını ancak Allah bilebilir, kimse öngöremez teknik detay için compiler dökümanlarına bakmak lazım.
"UB ne olacağını ancak Allah bilebilir" cümlesi Necati ERGİN 'i hatırlatıyor.
Teşekkürler.
UB’nin bugüne kadar fark edilmemesinin asıl nedeni sanırım, yalnızca entity->GetSectree() != this tutarsızlığı oluştuğunda tetiklenmesidir. Normal InsertEntity/RemoveEntity akışı bu ilişkiyi tutarlı tuttuğundan sorunlu dal muhtemelen hiç veya çok nadir çalışıyor; çalıştığında da silinen düğümün belleği hemen bozulmadığı için kod şans eseri devam edebiliyor.C++:template <class _Func> void for_each_entity(_Func & func) { itertype(m_set_entity) it = m_set_entity.begin(); for ( ; it != m_set_entity.end(); ++it) { LPENTITY entity = *it; // <Factor> Sanity check if (entity->GetSectree() != this) { sys_err("<Factor> SECTREE-ENTITY relationship mismatch"); m_set_entity.erase(it); continue; } func(entity); } }
Bu kodda UB var;
it erase edilip continue statement yazılmış. erase(it) sadece silinen elemana ait iterator'ı invalidate eder, statementda loop invalidate edilmiş iteratörü increment ediyor, olması gereken "it = m_set_entity.erase(it)" yazıp for yerine while döngüsüne çevirmek (erase zaten bir sonraki geçerli iterator'ı döndürüyor). Neyse, biraz daha inceleyip özetle C++20 için şöyle bir çözüm üretebilirsiniz;
C++:template <class _Func> void for_each_entity(_Func & func) { std::erase_if(m_set_entity, [this](LPENTITY entity) { if (entity->GetSectree() != this) { sys_err("<Factor> SECTREE-ENTITY relationship mismatch"); return true; } return false; }); std::ranges::for_each(m_set_entity, std::ref(func)); }
UB ise neden bugüne kadar patlamadı derseniz adı üstünde UB ne olacağını ancak Allah bilebilir, kimse öngöremez teknik detay için compiler dökümanlarına bakmak lazım.
"UB ne olacağını ancak Allah bilebilir" cümlesi Necati ERGİN 'i hatırlatıyor.

Teşekkürler.
Bu Denli Yararlı Bölümüne Gayet Uygun Olan Güzel Paylaşımların İçin Teşekkür ederim
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 20
- Görüntüleme
- 916
- Cevaplar
- 9
- Görüntüleme
- 533
- Cevaplar
- 3
- Görüntüleme
- 601
- Cevaplar
- 15
- Görüntüleme
- 869
