G++ Always Backward-Compatible with "Older" Static Libraries

g++ always backward-compatible with older static libraries?

The G++ ABI for C++98 code is backward compatible, all the way back to GCC 3.4

So if you compile and link your final executable with GCC 4.8 you can link to objects and libraries built with anything from GCC 3.4 to 4.8 (but no newer)

The C++11 ABI is the same as the C++98 ABI and the standard library types that are common to both C++98 and C++11 have the same definitions, (ignoring GCC 4.7.0 and GCC 4.7.1, which had ABI incompatibilities in std::pair and std::list when using C++11, which have been fixed in 4.7.2 and later versions) so you can link C++98 and C++11 code together (unless the C++11 code was built with GCC 4.7.0 or 4.7.1)

However some C++11 library types are not stable yet and change between releases, e.g. because they were first shipped before the final C++11 standard and had to be changed to match the final rules. So it's not necessarily safe to mix C++11 code built with GCC 4.6 and C++11 code built with GCC 4.8

For your case, where all the C++11 code is built with GCC 4.8 that will be OK. If you upgrade the compiler you should rebuild all the C++11 code with the newer GCC to be safe. (You don't need to rebuild the C++98/C++03 code)

Are newer apache commons libraries compatible with older ones

From the release notes for 4.0 version:

To help with the migration to this new version, the package has changed to "org.apache.commons.collections4", thus it is possible to have both commons-collections versions in the classpath.

Source: https://commons.apache.org/proper/commons-collections/release_4_0.html

This means that you can include both versions in your classpath without name collisions.

Is D backwards compatible with C if you use the C libraries?

There are several subtleties in D that can make C code not behave exactly as you may want it to. For instance, integer promotion rules are not quite the same (but almost), and initialization rules are different (floating point values -- including arrays of such -- are initialized to NaN, for example). Further, C function pointer syntax was deprecated recently, so you might have to translate some C type syntax to the equivalent D syntax.

In general, though, there is great focus on backwards compatibility, and most C code should compile fine (or with a very minor amount of changes) in D with the same semantics as in C.

Also note that std.c is deprecated; please use core.stdc instead.

Does using -std=c++11 break binary compatibility?

An authoritative reference can be found in gcc's C++11 ABI Compatibility page.

The short summary is: the are no language reasons the ABI gets broken but there are a number of mandated changes which cause the standard C++ library shipping with gcc to change.

is it possible to link a library compiled with c++11 to a code which needs to be compiled with c++03

Yes, it's possible as long as you use the same libstdc++ ABI, and as the new C++ 11 ABI has been introduced with g++ 5.1 (see using dual abi), it should be ok for you.

edit : see this answer for a more complete answer, specially regarding ABI incompatibility with g++ 4.7.0 and g++ 4.7.1

Use both static and dynamically linked libraries in gcc

Statically linking against any system library, and especially against libc, on modern UNIX or Linux systems makes the binary significantly less portable. Just don't do it.

Instead, use backward compatibility (binaries linked on an older system continue to run on all newer ones) to your advantage, either by linking your binary on an old system (I use RedHat 6.2, and I have not seen a Linux system where my binary will not run in the last 8 years), or by using something like autopackage (which has been deleted after this answer was written).

To answer your original question:

gcc main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic

will cause linker to use archive version of libfoo. [It is important to have the trailing -Wl,-Bdynamic precisely so you don't force static libc.]

Producing a library with a recent gcc and consuming it with an older gcc - Why are there issues despite the same C++ version?

Does it mean that in general, it is necessary but not sufficient for the
producer and the consumer of a library to use the same C++ version (and the > same ABI) ?

Correct. Backwards/forwards compatibility is not defined just by the C++ language version used when compiling source code. Backwards/forwards compatibility is a complicated topic of its own. But I'll just give a simple contrived, example that illustrates some underlying concepts.

Let's simplify what a std::string is. It's basically a pointer, and the number of characters in the string:

namespace std {

class string {
char *chars;
size_t nchars;
public:
// Constructors and other methods.
};
}

The real std::string is somewhat more complicated (and would use symbol names that are reserved for C++ implementations, but that's immaterial). This is just a simplified illustration. std::string existed even before C++11. So, things roll along, over the years, and your C++ compiler has been updated to C++20. For whatever reason its C++ library decided to change this class slightly:

namespace std {

class string {
size_t nchars;
char *chars;
public:
// Constructors and other methods.
};
}

At this point you can choose to instruct your new C++ compiler to compile only at the C++11 language revision. This will allow only C++11 language features. However the resulting binary code still will not be binary-compatible with code that was built by an older version of the C++ compiler, which was compiled with an incompatible class layout.

In general: in order for C++ code built by a new compiler to be binary compatible with code built by an older compiler, an explicit compilation/configuration option would be needed. It's certainly possible that this is this might be the option that specifies the general C++ language version, but just doing that is not generally sufficient. All that does is instruct the compiler which language version to use for compiling the C++ code. Newer language versions obsolete/deprecate features from earlier versions, and the purpose of the language option is to allow source code written for an earlier version of the C++ standard to be compiled, by the current C++ compiler. This is not the same thing as backwards/forwards compatibility.

Static initialization and destruction of a static library's globals not happening with g++

.a static libraries contain several .o but they are not linked in unless you reference them from the main app.

.o files standalone link always.

So .o files in the linker always go inside, referenced or not, but from .a files only referenced .o object files are linked.

As a note, static global objects are not required to be initialized till you actually reference anything in the compilation unit, most compilers will initialize all of them before main, but the only requirement is that they get initialized before any function of the compilation unit gets executed.



Related Topics



Leave a reply



Submit