[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