[Development] inline namespaces as a versioning tool (was: Re: QList)
Olivier Goffart
olivier at woboq.com
Thu Mar 30 11:31:11 CEST 2017
On Donnerstag, 30. März 2017 11:08:45 CEST Marc Mutz wrote:
> 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?
That works fine as long as there is only one library involved.
It stops working once the library is used in the ABI of another library.
Example: Qt used by KDE frameworks used by applications. Or stdlib used in the
ABI of Qt.
Imaging we have a ExLibrary that links against Library:
ExLibrary:
EXLIB_EXPORT void exUseFoo(Foo);
EXLIB_EXPORT Foo exGetDefaultFoo();
ExLibrary @ Library V1
-> exports "exUseFoo(v1::Foo)"
-> exports "exGetDefaultFoo()" returning an object v1::Foo
ExLibrary @ Library V2
-> exports only "exUseFoo(v2::Foo)"
-> still exports "exGetDefaultFoo()", but it returns a v2::Foo now, which
does not have the same layout
The problem is: as ExLibrary gets recompiled against the new version of
Library, it no longer exports the old symbols.
--
Olivier
Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
More information about the Development
mailing list