问题
I know that in principle this is probably undefined behaviour, but in the interest of dealing with a large project, here's my question about GCC:
Suppose I compile one transation unit with gcc -std=c++98
, and another with -std=c++11
, using the exact same compiler installation. Is there any sort of guarantee that I can link the two object files and obtain a well-defined program?
As far as I can tell, the potential problems can only come from different views of the library headers due to differing macros, and those in turn would at best add new member functions, but never member objects, to the standard library classes.
Would this somehow make it acceptable to compile different parts of a larger project with different language dialect options?
Update: I should add an orthogonal question: What about using two different versions of GCC (say 4.3 and 4.6), but wht the same dialect option (-std=c++98
)? The listing in this GCC documentation seems to suggest that the library is compatible in both directions between 4.2.2 and 4.6.
回答1:
A priori, no. The safest solution is to assume that all of the compiler options are identical, except when the compiler specifically documents that the option doesn't affect binary compatibility. (Documentation which is sorely lacking in most compilers.) In practice, in the lack of documentation, it seems a safe bet that options which control warnings (-W...
in g++) won't affect binary compatibility, and that options which affect code generation (language level, etc.) might: g++ generally maintains compatibility across different levels of optimization, where as VC++ doesn't.
Another real problem is defining preprocessor symbols in the command line. Again, the safest bet is that all of the defines be identical, but also again, some common sense is in order: one can hardly expect the standard library to have been compiled with preprocessor symbols which are used in your project (things like MYPROG_CONFIG_FILE_LOCATION
, say). On the other hand, be aware that preprocessor definitions of _GLIBCXX_DEBUG
and _GLIBCXX_DEBUG_PEDANTIC
will affect binary compatibility (although g++ ensures that you will get a library version which works with them if you use them consistently).
With regards to your question: I would not expect to much impact on binary compatibility due to standard version, but it would hardly surprise me if the choice affects some pre-defined preprocessor symbols, in a way that would break binary compatibility in the library, much as if you'd compiled some of the modules with _GLIBCXX_DEBUG
, and some without. It might work, but I wouldn't count on it.
回答2:
I know that in principle this is probably undefined behaviour,
It's not.
Suppose I compile one transation unit with
gcc -std=c++98
, and another with-std=c++11
, using the exact same compiler installation. Is there any sort of guarantee that I can link the two object files and obtain a well-defined program?
Yes, this is supported and works (there are exceptions, like enabling Debug Mode in one object and not the other, or using explicitly-ABI-changing options like -fshort-enums
in one and not the other, but that should be obvious because that won't work even if you use the same -std
option for both objects).
As far as I can tell, the potential problems can only come from different views of the library headers due to differing macros, and those in turn would at best add new member functions, but never member objects, to the standard library classes.
Right.
Would this somehow make it acceptable to compile different parts of a larger project with different language dialect options?
For GCC, yes, absolutely. As proof it's OK, consider that libstdc++.so
itself contains some objects built with -std=c++98
and some built with -std=c++14
.
Update: I should add an orthogonal question: What about using two different versions of GCC (say 4.3 and 4.6), but wht the same dialect option (-std=c++98)? The listing in this GCC documentation seems to suggest that the library is compatible in both directions between 4.2.2 and 4.6.
Not in both directions, you would need to use the libstdc++.so
from GCC 4.6 (or newer), because the object compiled with that version might depend on symbols that were introduced in the newer version and are not present in the older libstdc++.so
library.
Some related info at https://stackoverflow.com/a/49119902/981959
回答3:
Language ABI is the same, but STL ABI is different. See https://gcc.gnu.org/wiki/Cxx11AbiCompatibility
So do not recommend mixing libraries compiled with -std=c++98 -std=c++11. You may get crashes when passing data across image boundaries.
(It may work if you only call extern "C" functions and pass only PODs).
Also see related: Mixing different C++ standards with GCC
来源:https://stackoverflow.com/questions/10717106/can-different-gcc-dialects-be-linked-together