Stefan Teleman wrote:
> 2.2. C++ ABI Considerations
>
> The C++ Language Standard [ ISO/IEC 14882:2003 ] [4] did not
> define an ABI for the C++ Programming Language. Although several
> efforts aimed at defining a common C++ ABI have existed in
> the past, no consensus was ever reached. As a direct result of
> this lack of an unified C++ ABI, binary object code emitted by
> different C++ compilers is not interchangeable, and is likely
> to be binary incompatible across different C++ compilers, or
> different C++ runtime environments. Simply put, binary object
> code resulting from the compilation of C++ Language code is
> dependent on, and tied to, the compiler emitting it, and to the
> compiler which has emitted the binary object code for the C++
> runtime, and for the Standard C++ Library.
>
> For the purposes of delivering and maintaining a coherent,
> consistent and compatible C++ ABI, this Integration of QT3
> will be built with the Sun Studio compiler suite, which has
> maintained ABI C++ ABI compatibility since Release 5.0
> [ Workshop 5 ]. The Sun Studio compilers are supported by
> Trolltech ASA.
I believe the current ARC rules for C++ ABI's are currently those
specified in section 4.1.8 of the opinion of PSARC/2002/348 - unfortunately,
that case doesn't seem to be published on OpenSolaris.org right now
(hence the cc to arc-discuss to request that either it be published or the
C++ requirements be extracted and published as a C++ ARC Best Practices,
and potentially reviewed to see if any of the recommendations have changed
in the past 5 years). I think you've met all of these in your draft,
just not explicitly stated so.
For immediate reference, the relevant sections of the opinion are:
4.1 C++ ABI
The semantics of C++ make it much harder to maintain binary
compatibility while evolving a library which presents a C++
interface. In particular, the committee is concerned that
clients of an older shared library can safely use a newer
version and that the constraints on library maintenance
required to meet that goal can be expressed without undue
complexity.
4.1.1 Problem Areas
The following elements are among those which contribute to
the ABI of a library whose API is defined in C++:
+ - template definitions visible to application
+ - inline function definitions visible to application
+ - Standard Library version (if used inside the library)
+ - compiler version and options
+ - complete class/struct definitions visible to
application
where visible to the application means present in any
include file specified to define the libraries API and any
nested includes.
All these elements must only evolve in a compatible way.
This whole discussion assumes that any evolution of the API
maintains compatibility - i.e. none of the elements of the
ABI change their meaning. Also everything in this
description is worthless if the library API lies - i.e. the
definitions referenced when building the library don't match
those in the API.
4.1.2 Sameness
Several of the sections below require that various
definitions be the same. The simplest definition of "same"
is textually identical. However, two definitions that scan
into the same token stream after preprocessing also are the
same. Another loop hole in the definition of sameness is
that the ABI is not affected when function arguments, local
variables, data members, or enumeration constants are renamed.
4.1.3 Templates and inline functions
Use of either of those two facilities incorporates details
of the library implementation into the application. The
consequence is that from the perspective of the ABI no C++
object is opaque. Any change to a library data structure may
invalidate the application. Having template/inline
definitions be the same between library versions obviously
preserves compatibility. However, changing a function's
implementation is O.K. in those cases in which the old
version would still work.
4.1.4 Standard Library
The standard library is heavily based on inline and/or
template functions (some implementations have almost no
shared library component) and different vendor's libraries
use very different internal structures. As a result all C++
code that will end up running in the same process should be
built using compatible versions of the same shared library.
The Forte default standard library is guaranteed to be
stable across releases.
4.1.5 Compiler differences
Name mangling, implementation of virtual functions, and
class layout are among the areas not covered by any
standard. No two vendors agree. Some, like GNU, make changes
release to release. Also code generated by different
compilers require separate run-time support code. Frequently
the different support libraries don't coexist. While
exceptions are possible, the safest constraint is to require
that all C++ code that executes in the same process be
compiled with the same compiler. All Forte C++ compilers -
compiler version 5.1 or newer - can be considered as the
"same" when run with option "-compat=5" (currently the
default). (The one exception is that Forte doesn't support
linking code generated by a later compiler than the one
doing the linking - a limitation that isn't relevant to use
of shared libraries.)
4.1.6 Modification of Class definitions
Because of the way inheritance and virtual functions are
implemented few changes to class definitions can be
guaranteed compatible. For example: adding a private data
member to the end of a class may affect child classes. You
can add non-virtual member functions and static function and
data members to a class without breaking binary
compatibility. You might break source compatibility if added
functions overload existing class members. Again keeping
class definitions the same between versions of the library
is the safest strategy.
4.1.7 Safe Additions
Adding new class, function, or data declarations at file or
namespace scope will not break binary compatability. You
might break source compatibility if added functions overload
existing ones and adding a new declaration at file scope
might cause name collisions. (Note: the C++ namespace
mechanism is a much better way to avoid name collisions than
the C technique of starting every function name with a
unique prefix. No C++ library intended for wide use should
export file scope definitions.)
4.1.8 A Practical Policy for Binary Compatibility
A library presenting a C++ API can maintain a stable ABI if
the following restrictions are obeyed:
1. compile with the Sun C++ compiler in standard mode
(-compat=5)
2. when building the library include all files which
define the external API
3. keep the files defining the external API the "same" or
augment them only as described just above.
These restrictions are sufficiently straight-forward that
the committee recommends that any project willing to
formally agree to accept these requirements be permitted to
supply a library with a C++ interface. Any user of the
library must be willing to accept restriction 1.
The committee was concerned about how the restrictions
enumerated above could be communicated and enforced. It was
decided to establish a policy that a library exporting a C++
interface not be allowed to classify that interface either
"Evolving" or "Stable". The stability level recommended for
use of the library within Sun should be "Contracted
Consolidation Private" with the contract (see [6])
enumerating the restrictions.
--
-Alan Coopersmith- alan.coopersmith at sun.com
Sun Microsystems, Inc. - X Window System Engineering