[Development] inline namespaces as a versioning tool (was: Re: QList)
Marc Mutz
marc.mutz at kdab.com
Thu Mar 30 11:08:45 CEST 2017
On Thursday 30 March 2017 08:41:51 Olivier Goffart wrote:
> On Donnerstag, 30. März 2017 08:32:24 CEST Marc Mutz wrote:
> > On Thursday 30 March 2017 08:18:52 Olivier Goffart wrote:
> > > On Donnerstag, 30. März 2017 07:20:11 CEST Marc Mutz wrote:
> > > > On Wednesday 29 March 2017 22:12:30 Thiago Macieira wrote:
> > > > > On quarta-feira, 29 de março de 2017 11:11:58 PDT Marc Mutz wrote:
> > > > > > Keyword: inline namespaces. This is the C++ mechanism for API
> > > > > > versioning. It allows to make that totally transparent. Why you
> > > > > > find that so odd as to be lacking for words is beyond me.
> > > > >
> > > > > Inline namespaces do not solve the binary compatibility problem.
> > > > > They should not be used in Qt API for versioning.
> > > > >
> > > > > Instead, do what you said before: create a V2 class.
> > > >
> > > > Since the two are totally identical, except that inline namespaces
> > > > are transparent to the user, please explain what leads you to this
> > > > distinction.
> > >
> > > Library 1:
> > > inline namespace v1 { class Foo {}; }
> > >
> > > Library 2:
> > > LIBRARY2_EXPORT void registerPlugin(Foo*);
> > >
> > > -> symbol gets mangled as "registerPlugin(v1::Foo*)"
> > >
> > > Application:
> > > registerPlugin(new Foo);
> > >
> > > -> calls exported symbol "registerPlugin(v1::Foo*)"
> > >
> > > When Library 1 puts Foo in the v2 inline namespace, recompile Library2
> > > and
> > > the exported symbol becomes "registerPlugin(v2::Foo*)". If Application
> > > is not recompiled, it will not work as the old symbol is no longer
> > > found.
> >
> > Well, of couse. That's like removing the QFoo overload when you add
> > QFooV2. Don't do that. You need to keep the v1::Foo definition as well
> > as the v1::Foo overload, just as you need to keep the QFoo definition
> > and the QFoo overload, when you add v2.
>
> What I meant is that Library 1 becomes, in its next version
>
> namespace v1 { class Foo{}; }
> inline namespace v2 { class Foo{}; }
>
> It keeps v1::Foo, but puts v2::Foo in the inline namespace.
>
> If you don't use "inline namespace v2", that means users needs to
> explicitly use v2::Foo to use the new features. So it is no longer
> "transparent to the user"
Ok, no.
library V1:
inline // this inline is optional for V1 - users with compilers without
// support for them need to write v1:: explicitly, or it can be
// reasonably emulated with a ...
namespace v1 { class Foo{ int i, }; }
// ... using v1::Foo, here
LIB_EXPORT void useFoo(Foo); // actually v1::Foo
user V1:
useFoo(Foo{}); // actually v1::Foo
library V2:
namespace v1 { class Foo{ int i; } } // from V1 of library
inline
namespace v2 { class Foo{ v1::Foo f; double d; } // adds a double member,
// reuses v1::Foo
LIB_EXPORT void useFoo(v1::Foo); // from V1 of library
LIB_EXPORT void useFoo(Foo); // actually v2::Foo
user V2 @ library V2:
useFoo(Foo{}); // actually v2::Foo
user V1 @ library V2:
(compiled and continuing to run as) useFoo(v1::Foo{});
-> totally transparent, BC and SC
Where's my mistake?
> Personally I prefer having a pimpl so I can just add or change members.
>
> (Note that if the class is at least sizeof(void*) and that none of its
> member are accessed in inline methods or ctors/dtor, we can add a pimpl
> later, when we need it.)
The point is to have thin abstractions be completely inline. QSizePolicy is a
good example. It's full now. If ever we need to add a new member, we need
QSizePolicyV2.
Note that I'm not saying that we should version QString or other such core
classes like this. This is completely impractical. But we have tons of small
classes that are used in only a handful of APIs and they would definitely
benefit from this. QStyleOption, QSizePolicy, most QSsl value types. Stuff
like Q*DialogOptions. There's just no reason to pay the pimpl price for these
anymore.
Thanks,
Marc
--
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts
More information about the Development
mailing list