This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: shared object, inline members and backward compatibility


> 1 - I have a inline static public member function. If I drop an assert from
> it, does it break backward compatibility?

Sort of.

If your SDK contains inline functions that the consumer uses in their code,
then changes to your SDK's inline functions is not simply a "drop in this
new .so and enjoy", it's a "drop in this new .so, rebuild all your files,
and enjoy".

For that reason, as an SDK kind of guy, I strongly discourage any and all
inline functions in the public portion of the SDK (that being the part that
the consumer of the SDK sees).

I have a "for instance" example, of a real world scenario.  In my own SDK,
one of the routines did not declare a destructor.  Which means that the
compiler would synthesize an inline destructor for me.  (I'm betting you can
already see where this is going.)

Since the class was designed using a Proxy-Implementation pattern (aka PImpl
pattern), using std::auto_ptr to hold the forward declared implementation
class in the public header file, which means when the destructor of the
proxy class was called in the USERS code (since the destructor was inline),
the USERS' code needed to have visibility access to the implementation
class.  Which pretty much defeats the purpose of the Proxy-Implementation
pattern.

Making the destructor be explicitly defined fixed the problem.  But was a
bit of a mess since all the consumers had to be recompiled.

Fortunately, this is an internal SDK, and we work tightly with the consumers
of the SDK.  But I can imagine a public SDK were this kind of thing would
cause a lot more disruption.

ASIDE:  I prefer the Proxy-Implementation pattern that uses an interface API
class (with virtual functions) as the proxy, static factory functions, and
the backside implementation being done through inheritance.  I don't like
the class Foo { class FooImpl; std::auto_ptr<FooImpl> mImpl; }; type of
pattern, such as described above.

Templates are of special concern, since they are emitted into the consumers
translation units.  As such, changes to them pretty much require a "rebuild
your world" to all the SDK consumers.

> 2 -How can I know if a change in one of my libraries will break
> compatilibity? I mean some paper, utility, etc.

Because of the fragile base class problem in C++, great care must be taken
to avoid breaking compatibility, if you are in a situation where your .so
can be dropped in independently of recompiling the consumer of your .so.

Inline routines (explicit ones, or implicit ones) cause another kind of
fragility.  A kind that can be avoided, by avoiding inline routines in your
header files.

I don't even know where to begin to provide a list of issues.  The mind
boggles.

This book should be of assistance...
Large-Scale C++ Software Design by Lakos
http://www.amazon.com/dp/0201633620

HTH,
--Eljay


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]