Subject: Re: [boost] [Booster] Or boost is useless for library developers
From: Artyom (artyomtnk_at_[hidden])
Date: 2010-05-16 00:18:14
> First let's examine a library implemented as header only.
> a) version 0 - a bunch of headers.
> User builds his code and is pleased as punch.
> b) version 1 - same bunch of headers + plus a few more.
> Also the original classes have some new functions - BUT
> of the existing functions are eliminated nor have a change
> Where is the incompatibility.
In this case two library are compatible unless:
- New introduced functions are virtual and user derives its class
- The class has new members - so layout of the class has changed.
boost->v1-50 shared_ptr uses sp_counted_base that has following members
boost->v1->51 shared_ptr implemented atomic ops for this platform and
sp_counted_base has following members:
ABI broken since in one part it uses atomic ops and not locks mutex
in other it uses only mutex - code is not thread safe.
> case II
> A library that has to be built as either a DLL or a static
> a) version 0 - bunch of headers and source modules.
> User is pleased as punch same as above.
> b) version 1 - same as above + changes in function
> Now there a library/dll which is different than the one
> produced by
> version 0.
> User rebuilds his app against the new library.
Note, once user rebuilds the library against new library everithing
is fine as long as API compatible (and boost keeps the API **mosty**
This is not the issue.
> c) User rebuilds his app and sends it to his customers how
> have the
> DLL library built in version 0. if he's using a
> static library there's
> no problem. If he's using a DLL the application will
> run against
> the original version DLL with no problem.
Same, rebuild solves the issue.
> Sooo it seems to me that the only situation which would
> "break binary compatibility" would be when ALL the
> are true.
> i) The library is not a header only library
> ii) class definition includes new data members in one or
> more interface.
> iii) one library is distributed separately from it's
> Am I getting this right? If so it would seem that
> there's not
> much that "breaks binary compatibility" and that it
> take too much effort to avoid this.
No, it is much more complicated. There actually two major cases, that
should be solved.
(a) User has a library libfoo.(so|dll|lib|a) that was compiled against
header only or linked (statically or dynamically) boost-1.33.1
Now, customer what to use libfoo but he needs boost-1.35.0
He can't because 1.35 is not ABI compatible to 1.33.1
So any class that passes between libfoo and customer app that
uses boost would have danger of crash.
More then that, under ELF platforms (Linux, Solaris, BSD) there is
even bigger issue because this may happen even if you do not
share classes explicitly between libfoo and your app. Because all
symbols are uniquely mapped so user of libfoo may get boost-1.35
symbols even if they are used internally.
(b) User developed its application against boost-1.33.1 dll/so, now after
system upgrade new version of boost installed now its application
would not start because no 1.33 available.
This is little bit simple case because it just need to keep two
version of boost dll 1.33.1 and 1.35.
The first issue is my biggest problem using boost-as-is.
Now how ABI can be broken:
- sizeof of class has changed
- new virtual function was introduced
- the semantics of private members had changed and they are used from
header only libraries.
- and much more
This is great tutorial about it:
Now, you will see that keeping ABI is quite tricky.
I hope that this explains the issue.