Używam std::aligned_storage
jako pamięci wewnętrznej dla wariantu szablonu. Problem polega na tym, że po włączeniu -O2
w gcc zacznę otrzymywać ostrzeżenia o "przeszkadzającym wskaźniku typu" dereferencing ", które przerwie ścisłe aliasowanie.Jak uniknąć ścisłych błędów aliasingu podczas korzystania z polecenia adjust_storage
Prawdziwy szablon jest znacznie bardziej skomplikowane (typ sprawdzana przy starcie), ale minimalny przykład wygenerować ostrzeżenie jest:
struct foo
{
std::aligned_storage<1024> data;
// ... set() uses placement new, stores type information etc ...
template <class T>
T& get()
{
return reinterpret_cast<T&>(data); // warning: breaks strict aliasing rules
}
};
jestem całkiem pewny boost::variant
robi w zasadzie to samo, co ten, ale nie mogę znaleźć sposobu na uniknięcie tego problemu.
Moje pytania są następujące:
- W przypadku korzystania
aligned_storage
w ten sposób jest niezgodny strict-aliasing, jak należy go używać? - Czy istnieje rzeczywiście problem z aliasingiem ścisłym w
get()
, biorąc pod uwagę, że w tej funkcji nie ma innych operacji opartych na wskaźnikach?- Co się stanie, jeśli zostanie wstawiona linia
get()
? - Co z numerem
get() = 4; get() = 3.2
? Czy ta kolejność może być ponownie uporządkowana z powodu różnych typów?int
ifloat
?
- Co się stanie, jeśli zostanie wstawiona linia
powoduje wyrównanie wpływa problem aliasingu w jakikolwiek sposób ?! spodziewaj się, że jest to część tego powodu (ale to nie zmienia w ogóle punktu, w którym standard je fobiduje, czy nie?) – dhein
@Zaibis Nie, używając 'aligned_storage' w przeciwieństwie do jakiegokolwiek innego typu jako bufora shouldn ' t zrobić jakąkolwiek różnicę. Powodem, dla którego określiłem tutaj "matching_storage", jest to, że wydaje się, że został zaprojektowany z myślą o takim użyciu. – marack
@marack: nie powinieneś (i tak naprawdę nie wolno ci) korzystać bezpośrednio z "aligned_storage". Zmieniłem moją odpowiedź, aby spróbować uczynić to (jeszcze bardziej) bardziej przejrzystym. – rici