Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can different GCC dialects be linked together?

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.

like image 410
Kerrek SB Avatar asked May 23 '12 09:05

Kerrek SB


People also ask

What is linking gcc?

Linking is performed when the input file are object files " .o " (instead of source file " . cpp " or " . c "). GCC uses a separate linker program (called ld.exe ) to perform the linking.

Can you mix C++ versions?

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.

What option should be added to a gcc command in order to link in functions from a library?

Short answer: If you want to use functions from the math library in C, it's not enough to put #include<math. h> at the top of your source code. In addition, you must add the - lm flag to the gcc compiler command in order to use math functions in your C code.

When compiled from command line what are linking options?

The -Wl, is the start of the linker command options, which you have --export-dynamic as the single linker option. This tell gcc to compile the file using the compiler options shown (and those generated from the call to pkg-config , then call the linker With linker options ,--export-dynamic .


2 Answers

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.

like image 67
James Kanze Avatar answered Oct 18 '22 12:10

James Kanze


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

like image 45
Jonathan Wakely Avatar answered Oct 18 '22 12:10

Jonathan Wakely