Binary compatibility
In general, C++ objects built with IBM® Open XL C/C++ for AIX® 17.1.0 are binary compatible with C++ objects built with the Clang-based front end of IBM XL C/C++ for AIX 16.1.0 that is invoked by xlclang++.
The exception is that object files created by IBM XL C/C++ for AIX 16.1.0 with the -qpdf1 option need to be recompiled because the object files make calls to a different PDF library from the ones used in this compiler. Refer to the Profile Guided Optimization (PGO) topic for more information.
std library libc++, and causes a breakage in C++ binary
compatibility. Therefore, C++ object files built with IBM Open XL C/C++ for AIX
17.1.0 are not
directly interoperable with C++ object files generated by the XL-based front end of IBM XL C/C++ for AIX
16.1.0 or earlier
releases, which is invoked by xlC. You must recompile your classic programs with
IBM Open XL C/C++ for AIX
17.1.0 to
solve such binary incompatibility and link object files successfully.C objects built with IBM Open XL C/C++ for AIX 17.1.0 are binary compatible with C objects built with IBM XL C/C++ for AIX 16.1.0 or earlier releases when the symbol names with external linkage contain only the dollar sign and the characters from the basic character set.
Compatibility with Classic XL C++ object files
- C++ object files built with IBM Open XL C/C++ for AIX. These object files utilize interfaces provided by C++ runtime libraries
libc++.a,libc++abi.a, andlibunwind.a, which are from thelibc++.rte,libc++abi.rte, andlibunwind.rtefileset, respectively. - C++ object files built with the Clang-based front end of IBM XL C/C++ for AIX
16.1.0. These
object files utilize interfaces provided by C++ runtime
libc++.a, which is from thelibc++.rtefileset.
- C++ object files built with the XL-based front end of IBM XL C/C++ for AIX
16.1.0 or earlier
releases. The object files utilize interfaces provided by C++ runtime
libC.a, which is from thexlC.rtefileset.
Different mangled names
The names of C++ functions and other entities are
mangled using different name mangling schemes in libc++ ABI and libC ABI to prevent linking of
incompatible code. libc++ ABI utilizes the CXA mangling scheme that is defined in the Itanium C++
ABI specification, while libC ABI uses the IBM proprietary mangling scheme. Consequently, the
corresponding symbols for a C++ function in these ABIs are different; for example, the symbol of C++
function func() is _Z4funcv in libc++ ABI, whereas it is
func__Fv in libC ABI. In the CXA mangling scheme, mangled names have the
_Z prefix.
Different object model and layout
The C++ object model and layout differ
between libc++ ABI and libC ABI. Accessing C++ objects from one C++ ABI in code that is compiled in
another C++ ABI results in undefined behavior, except where the type is subject to rules for
compatibility with C.
Different exception handling
The implementation of exception handling differs
between libc++ ABI and libC ABI. There are exception handling limitations when exceptions are thrown
from the libc++ ABI side and caught or unwound through the libC ABI side, or vice versa. Refer to
Exception compatibility for details.
Due to these differences, libc++ ABI and libC ABI are incompatible and can be considered as different languages, even though both are referred to as C++. However, they can still coexist in the same application with limitations. In such cases, there can be instances of different C++ runtimes coexisting in the same process space without interacting with each other. For example, input and output are buffered separately and are not visible to the other runtime.
Libraries built with coexisting shared objects
- The libc++ ABI or libC ABI shared objects in the library are mutually exclusive.
- Each shared object in the library that presents a C++ API surface supports only one of libc++ ABI and libC ABI.
- Exported symbols from these ABIs are disjoint.
- There are no cross references between libc++ ABI and libC ABI.
If the libc++ ABI and libC ABI shared objects have cross references, or if there is an executable file referencing symbols from two types of shared objects, the shared objects will be linked with the resulting executable file. This results in two different C++ runtime implementations coexisting in the same process space, which might cause unexpected behavior. To confirm the load dependencies of an executable, use the ldd command on the executable.
asm label.
In the following example, name externCFunctionV2 is used for the
externCFunction function in libc++ ABI and its original name
externCFunction is used in libC
ABI.#if defined(_AIX) && defined(__clang__)
extern "C" void externCFunction(void) asm("externCFunctionV2");
#else
extern "C" void externCFunction(void);
#endifExport only the desired symbols from these shared objects and ensure that exported symbols across
C++ ABIs in your shared objects do not overlap. To learn about how to export symbols, refer to
Symbol exports and visibilities. When an old C++ ABI
is no longer needed for linking new applications but you want to retain load compatibility, a shared
object can be made load-only with the strip -e command.
Unlike shared objects, where exported symbols are controlled by export lists or attribute visibility, having static archive members for both libc++ ABI and libC ABI in the same archive library might result in unexpected behavior. For example, static constructors for both libc++ ABI and libC ABI are executed by the resulting executable, which might not be expected. It is not recommended to include static archive members for both libc++ ABI and libC ABI in the same archive library unless the behavior is well understood.
The following example shows how to build a dual-ABI library from a single source to support both libc++ ABI and libC ABI:
$ cat build_example.sh
#!/usr/bin/ksh
rm -f xlc.shr.o ibmclang.shr.o libfunc.a xlc.a.out ibmclang.a.out
xlC -qmkshrobj func.cpp -o xlc.shr.o -bE:xlc.exp
ibm-clang++_r -shared func.cpp -o ibmclang.shr.o -bE:ibmclang.exp
ar -v -q libfunc.a xlc.shr.o ibmclang.shr.o
xlC main.cpp -o xlc.a.out libfunc.a -blibpath:.:/usr/lib
ibm-clang++_r main.cpp -o ibmclang.a.out libfunc.a -blibpath:.:/usr/lib
$ cat func.hpp
#include <iostream>
#if defined(_AIX) && defined(__clang__)
extern "C" void bar(void) asm("bar2");
#else
extern "C" void bar(void);
#endif
void func(void);
$ cat func.cpp
#include "func.hpp"
#if defined(_AIX) && defined(__clang__)
#define BUILD_COMPILER "build compiler is ibm-clang++_r"
#else
#define BUILD_COMPILER "build compiler is xlC"
#endif
void func(void)
{
std::cout << "func(): " << BUILD_COMPILER << std::endl;
}
extern "C" void bar(void)
{
std::cout << "bar(): " << BUILD_COMPILER << std::endl;
}
$ cat main.cpp
#include "func.hpp"
int main() {
func();
bar();
return 0;
}
$ cat xlc.exp
#!
func__Fv
bar
$ cat ibmclang.exp
#!
_Z4funcv
bar2
$ build_example.sh
$ xlc.a.out
func(): build compiler is xlC
bar(): build compiler is xlC
$ ibmclang.a.out
func(): build compiler is ibm-clang++_r
bar(): build compiler is ibm-clang++_r
$
In this example, the main program built with either the
xlC or ibm-clang++_r command can call both the
func and bar functions from the dual-ABI library. Shared object
ibmclang.shr.o in libfunc.a is built using the IBM Open XL C/C++
compiler. The shared object can be used by both IBM Open XL C/C++ for AIX and the Clang-based front end of IBM XL C/C++ for AIX
16.1.0. Because
ibmclang.shr.o has dependencies on the C++ runtime of the IBM Open XL C/C++
compiler, applications generated by the Clang-based front end of IBM XL C/C++ for AIX
16.1.0 require
the appropriate version of the IBM Open XL C/C++ for AIX runtime to be available on the system.
Similarly, ibmclang.shr.o can also be built using the Clang-based front end of
IBM XL C/C++ for AIX
16.1.0
and used by both IBM Open XL C/C++ for AIX and the Clang-based front end of IBM XL C/C++ for AIX
16.1.0.xlc.a.out and ibmclang.a.out in the example
above:$ ldd xlc.a.out
xlc.a.out needs:
...
/usr/lib/libC.a(shr.o)
...
/usr/lib/libC.a(shrcore.o)
/usr/lib/libC.a(ansi_32.o)
/usr/lib/libC.a(ansicore_32.o)
$ ldd ibmclang.a.out
ibmclang.a.out needs:
...
/usr/lib/libc++.a(shr2.o)
/usr/lib/libc++abi.a(libc++abi.so.1)
/usr/lib/libunwind.a(libunwind.so.1)
/usr/lib/libc++.a(libc++.so.1)
...
$According to the output, xlc.a.out has dependencies on the C++ runtime of the
classic XL C/C++ compiler, which is libC.a, but it does not have dependencies on
the C++ runtime of the Open XL C/C++ compiler, which are libc++.a,
libc++abi.a, and libunwind.a. On the other hand,
ibmclang.a.out has dependencies on libc++.a,
libc++abi.a, and libunwind.a but does not have dependencies on
libC.a.