Sto usando std::aligned_storage
come memoria di supporto per un modello di variante. Il problema è che, una volta abilitato -O2
su gcc, comincio a ricevere gli avvisi di "puntatore con puntatore di dereferenziazione che interromperà il rigoroso aliasing".Come evitare gli errori di aliasing severo quando si utilizza aligned_storage
Il vero modello è molto più complessa (tipo controllato in fase di esecuzione), ma un esempio minimo per generare l'avviso è:
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
}
};
Sono abbastanza sicuro boost::variant
sta facendo essenzialmente la stessa cosa come questa, ma non riesco a trovare il modo in cui evitano questo problema.
Le mie domande sono:
- Se si utilizza
aligned_storage
in questo modo viola rigoroso-aliasing, come dovrei essere usando? - Esiste effettivamente un problema di aliasing stretto in
get()
dato che non ci sono altre operazioni basate su puntatore nella funzione?- E se lo
get()
è in linea? - Che dire di
get() = 4; get() = 3.2
? È possibile riordinare quella sequenza a causa diint
efloat
di tipi diversi?
- E se lo
non l'allineamento influisce il problema aliasing in alcun modo ?! aspettarsi che sia parte del motivo (ma questo non cambia affatto al punto che lo standard lo fobide, non è così?) – dhein
@Zaibis No, usando 'aligned_storage' rispetto a qualsiasi altro tipo come un buffer shouldn ' t fare qualsiasi differenza Il motivo per cui ho specificato 'aligned_storage' qui è che sembra essere stato progettato pensando a questo tipo di utilizzo. – marack
@marack: non dovresti (e non ti è permesso) usare direttamente 'aligned_storage'. Ho modificato la mia risposta per cercare di renderlo (anche) più chiaro. – rici