On Wed, Jun 23, 2021 at 7:23 AM Trevor Saunders <tbsau...@tbsaunde.org> wrote: > > On Tue, Jun 22, 2021 at 02:01:24PM -0600, Martin Sebor wrote: > > On 6/21/21 1:15 AM, Richard Biener wrote: [...] > > > > > > But maybe I'm misunderstanding C++ too much :/ > > > > > > Well, I guess b) from above means auto_vec<> passing to > > > vec<> taking functions will need changes? > > > > Converting an auto_vec object to a vec slices off its data members. > > The auto_vec<T, 0> specialization has no data members so that's not > > a bug in and of itself, but auto_vec<T, N> does have data members > > so that would be a bug. The risk is not just passing it to > > functions by value but also returning it. That risk was made > > worse by the addition of the move ctor. > > I would agree that the conversion from auto_vec<> to vec<> is > questionable, and should get some work at some point, perhaps just > passingauto_vec references is good enough, or perhaps there is value in > some const_vec view to avoid having to rely on optimizations, I'm not > sure without looking more at the usage.
We do need to be able to provide APIs that work with both auto_vec<> and vec<>, I agree that those currently taking a vec<> by value are fragile (and we've had bugs there before), but I'm not ready to say that changing them all to [const] vec<>& is OK. The alternative would be passing a const_vec<> by value, passing that along to const vec<>& APIs should be valid then (I can see quite some API boundary cleanups being necessary here ...). But with all this I don't know how to adjust auto_vec<> to no longer "decay" to vec<> but still being able to pass it to vec<>& and being able to call vec<> member functions w/o jumping through hoops. Any hints on that? private inheritance achieves the first but also hides all the API ... > However I think that's a > separate issue and we can't and shouldn't fix everything at once. As > for slicing auto_vec<T, N> I think that mostly "works" given the same > conditions as for auto_vec<T, 0> because the base that gets coppied is a > pointer to a valid embedded vec the same as in the source object. So as > long as the source outlives the copy, and the operations on either > object do not trigger a resize you get away with it, as much as it is > playing with fire. Returning a auto_vec<T, N> sounds like a bug to > begin with, even if it worked correctly, but that aside, you can't > convert from auto_vec<T, N> to auto_vec<T, M> for n != M, so if the > function returns auto_vec<T> you can implicitly convert to vec<T> in the > caller, but you can't slice away part of the source object. Making more > things return auto_vec<T> certainly increases the number of places > conversions to vec<T> can take place and cause trouble, but you can't > fix everything at once, and its a preexisting issue, which would be the > same if the copy members were defined.