On Fri, Feb 24, 2023 at 09:55:13AM +0000, Jonathan Wakely wrote:
> > You would still be accessing past the end of the
> > vec<vl_embed>::m_vecdata array which is UB.
> 
> My thinking is something like:
> 
> // New tag type
> struct vl_relative { };
> 
> // This must only be used as a member subobject of another type
> // which provides the trailing storage.
> template<typename T>
> struct vec<T, va_heap, vl_relative>
> {
>   T *address (void) { return (T*)(m_vecpfx+1); }
>   const T *address (void) const { return (T*)(m_vecpfx+1); }
> 
>   alignas(T) alignas(vec_prefix) vec_prefix m_vecpfx;
> };
> 
> template<typename T, size_t N /* = 0 */>
> class auto_vec : public vec<T, va_heap>
> {
>   // ...
> private:
>   vec<T, va_heap, vl_relative> m_head;
>   T m_data[N];
> 
> static_assert(...);
> };

Maybe this would work, vl_relative even could be vl_embed.
Because vl_embed I believe is used in two spots, part of
auto_vec where it is followed by m_data and on heap or GGC
allocated memory where vec<..., vl_embed> is followed by
further storage for the vector.

        Jakub

Reply via email to