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

Reply via email to