[Development] Abandoning the container changes

Marc Mutz marc.mutz at kdab.com
Thu Jul 19 14:31:52 CEST 2012


On Thursday July 19 2012, joao.abecasis at nokia.com wrote:
> Marc Mutz wrote:
> > On Wednesday July 18 2012, joao.abecasis at nokia.com wrote:
> >> I think it would be feasible to do a binary-only break somewhere
> >> around the 5.2 timeframe (say, ~12 months) where we address this.
> >> Technically, this would be Qt 6, but user porting effort would be
> >> reduced to a recompile. The value of having a long lived (5 years?)
> >> binary compatible 5.x series is (IMO) low as there are quite often
> >> other reasons to recompile the stack.
> >
> > We don't even need to break binary compatibility. We could use inline
> > namespaces to let new code see the new containers while old code uses
> > the old ones. That will exclude non-C++11 compilers from seeing the
> > more efficient implementations, or else from the BC guarantee. Do we
> > care?
>
> It's a binary break because containers and their memory layout are part
> of function signatures in the ABI.
>
> We also don't want a price to be paid at the interface: you were calling
> a function and now just the function call has an additional cost of
> deep-copying the container, potentially breaking implicit sharing that
> was previously assumed to occur. This would be a silent change.

No, you would of course add an overload (where it matters).

Assuming we have

inline namespace v50 {
   class QVector ... ;
}
qFun(const QVector &); // implictly v50::QVector

now. In, say, v5.2 we'll change QVector's guts. We do so by adding a new 
implementation in namespace v52 and providing overloads for v50::QVector 
where it matters:

namespace v50 {
   class QVector ... ; // same as before
}
inline namespace v52 {
    class QVector ... ; // new impl, with conversion to/from v50::QVector...
}
qFun(const v50::QVector&); // old version, explicit namespace, required for BC
qFun(const QVector &); // new version (if necessary)

I'm not sure about forward-declarations, but at least inline namespaces are 
designed to prevent the user of a type from being able to distinguish whether 
it's in a namespace or a nested inline namespace. E.g., you can still 
specialise templates in the surrounding namespace:

template <>
class QVector<MyType> {...};

Inline namespaces are designed for library versioning. And seriously, 
regarding another copy vs. implicit sharing: Qt breaks behaviour at so many 
levels so often that users would hardly notice if there was some conversion 
going on, esp. as the conversion cost, if not negligible, would of course 
only be paid by old code (ie. qFoo(v50::QVector) would be implemented by 
converting the argument to v52::QVector and calling qFoo(v52::QVector)).

I'd say that people that need BC guarantees are used to this kind of thing, 
without having looked at it in details, glibc's library versioning is working 
in the same way, everything else would be a maintenance nightmare.

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions



More information about the Development mailing list