问题
For example could I mix a set of libraries that have been compiled in say GCC-4.6 with GCC-4.9.
I'm aware different compilers "breeds" such as VS cannot be with MinGW but can different generations of the same compiler? Are issues likely to occur? If so what?
回答1:
Different generations of the same compiler sometimes can be compatible with each other, but not always. For example, GCC 4.7.0 changed its C/C++ ABI, meaning libraries compiled with 4.7.0+ and 4.7.0- are not likely to be compatible with each other (so in your example, the library compiled with 4.6 will not be compatible with the library compiled with 4.9). There can also be ABI bugs within a given compiler release, as happened in GCC 4.7.0/4.7.1:
GCC versions 4.7.0 and 4.7.1 had changes to the C++ standard library which affected the ABI in C++11 mode: a data member was added to std::list changing its size and altering the definitions of some member functions, and std::pair's move constructor was non-trivial which altered the calling convention for functions with std::pair arguments or return types. The ABI incompatibilities have been fixed for GCC version 4.7.2 but as a result C++11 code compiled with GCC 4.7.0 or 4.7.1 may be incompatible with C++11 code compiled with different GCC versions and with C++98/C++03 code compiled with any version.
The GCC ABI Policy and Guidelines page indicates they try to maintain forward compatibility, but not backward compatibility:
Versioning gives subsequent releases of library binaries the ability to add new symbols and add functionality, all the while retaining compatibility with the previous releases in the series. Thus, program binaries linked with the initial release of a library binary will still run correctly if the library binary is replaced by carefully-managed subsequent library binaries. This is called forward compatibility.
The reverse (backwards compatibility) is not true. It is not possible to take program binaries linked with the latest version of a library binary in a release series (with additional symbols added), substitute in the initial release of the library binary, and remain link compatible.
That page also has some fairly lengthy explanations on the versioning system GCC uses to mark different versions of given components, as well as an explanation for the versioning behind GCC itself:
Allowed Changes
The following will cause the library minor version number to increase, say from "libstdc++.so.3.0.4" to "libstdc++.so.3.0.5".
Adding an exported global or static data member
Adding an exported function, static or non-virtual member function
Adding an exported symbol or symbols by additional instantiations
Other allowed changes are possible.
Prohibited Changes
The following non-exhaustive list will cause the library major version number to increase, say from "libstdc++.so.3.0.4" to "libstdc++.so.4.0.0".
Changes in the gcc/g++ compiler ABI
Changing size of an exported symbol
Changing alignment of an exported symbol
Changing the layout of an exported symbol
Changing mangling on an exported symbol
Deleting an exported symbol
Changing the inheritance properties of a type by adding or removing base classes
Changing the size, alignment, or layout of types specified in the C++ standard. These may not necessarily be instantiated or otherwise exported in the library binary, and include all the required locale facets, as well as things like std::basic_streambuf, et al.
Adding an explicit copy constructor or destructor to a class that would otherwise have implicit versions. This will change the way the compiler deals with this class in by-value return statements or parameters: instead of passing instances of this class in registers, the compiler will be forced to use memory. See the section on Function Calling Conventions and APIs of the C++ ABI documentation for further details.
Note the bolded bit. In a perfect world, GCC versions with the same major release number would be binary-compatible. This isn't a perfect world, so test very very carefully before you go mixing compiler versions like this, but in general you'll probably be okay.
回答2:
You can only mix generated binary files from different compilers or different versions of the same compiler if they are ABI (Application Binary Interface) compatible.
Things like:
- Calling procedure
- Name mangling
- Thread local storage handling
are all part of the ABI.
If one of these things change, you will find that you either get linker errors, crashes or other forms of unexpected behaviour. As a general rule, compiler vendors will often try maintaining at least backwards compatibility with older version, but there is no guarantee of this. As other have said you must either read the documentation or just recompile everything.
来源:https://stackoverflow.com/questions/23895081/can-you-mix-c-compiled-with-different-versions-of-the-same-compiler