On Fri, Feb 24, 2023 at 09:34:46AM +0000, Richard Biener wrote: > > Looking at vec<T, A, vl_embed>::operator[] which just does > > > > template<typename T, typename A> > > inline const T & > > vec<T, A, vl_embed>::operator[] (unsigned ix) const > > { > > gcc_checking_assert (ix < m_vecpfx.m_num); > > return m_vecdata[ix]; > > } > > > > the whole thing looks fragile at best - we basically have > > > > struct auto_vec > > { > > struct vec<vl_embed> > > { > > ... > > T m_vecdata[1]; > > } m_auto; > > T m_data[N-1]; > > };
Assuming a compiler handles the T m_vecdata[1]; as flexible array member like (which we need because standard C++ doesn't have flexible array members nor [0] arrays), I wonder if we instead of the m_auto followed by m_data trick couldn't make auto_vec have alignas(vec<vl_embed>) unsigned char buf m_data[sizeof (vec<vl_embed>) + (N - 1) * sizeof (T)]; and do a placement new of vec<vl_embed> into that m_data during auto_vec construction. Isn't it then similar to how are flexible array members normally used in C, where one uses malloc or alloca to allocate storage for them and the storage can be larger than the structure itself and flexible array member then can use storage after it? Though, of course, we'd need to test it with various compilers, GCC 4.8 till now, various versions of clang, ICC, ... Jakub