Library compatibility between C++11 and C++03 - c++

I am developing an application in C++11, using g++-4.7 and -std=c++0x.
My app is linked against some shared library compiled with g++-4.7, but without the -std=c++0x directive.
Unfortunately, nothing works, meaning that I have some strange behaviour when using the external library classes and methods. (Of course compiling my app without -std=c++0x works fine).
Is this an expected behaviour or it's a compiler bug?
Any workaround (something like the extern C keyword)?

The standard library has changed, and the -std=c++0x compiler flag will determine what part of the library is in use. By trying to use both versions in the same program you are breaking the One Definition Rule (for each used element in the standard library you have two definitions for the same identifier).
I don't think there is anything simple that can be done to overcome this limitation. You would have to ensure that you only use one version of the library (i.e. define the appropriate macros before inclusion of standard headers to disable C++11 inside those libraries), and even then I am not sure that the generated code would still not break the ODR (if the C++11 extensions compile the C++03 library code differently).

Related

Build Fails Using GCC-11 Due to Some Missing Standard Library Headers

After upgrading to gcc-11, which is shipped with Ubuntu 22.04, I started to get new compiler errors due to some missing Standard Library header files. Whereas previous gcc versions don't.
When I started to look into it, I learned from Porting to GCC 11 page, under the "Header dependency changes" section, that this is a new behavior due to some new specs in the standard itself.
Now, my question is: does the implementation of a particular C++ standard (i.e. C++17) change from one gcc version to another (i.e. gcc-9 and gcc-11)? I mean, how can the build fail if I'm building with different gcc versions but against the same C++ standard version (i.e. -std=c++17)?
And is that C++ Standard Library new requirement - of not to include other headers that were being used internally by the library - part of C++17 or C++20?
To get over this...
I manually included those header files where they were missing, and the build just succeeded.
However, I was expecting behavior to be consistent when I build against a certain C++ version with different gcc versions. Or, am I missing something?
Thanks to JaMiT note, I realized that I got the note from GCC wrong.
It's only their implementation of the Standard that got changed in GCC 11, and not the Standard itself.
When you thoroughly read the referenced section from that article, you can see that.
Header dependency changes
Some C++ Standard Library headers have been changed to no longer
include other headers that were being used internally by the library.
As such, C++ programs that used standard library components without
including the right headers will no longer compile.
The following headers are used less widely in libstdc++ and may need
to be included explicitly when compiled with GCC 11:
<limits> (for std::numeric_limits)
<memory> (for std::unique_ptr, std::shared_ptr etc.)
<utility> (for std::pair, std::tuple_size, std::index_sequence etc.)
<thread> (for members of namespace std::this_thread.)

Can I use a library developed in c++11 in c++17 code?

I'm working on a c++ project and I use c++17 as c++ standard. I've some library dependencies which has been developed using c++11. Are there any obstacles in using this library? Do I need to recompile it using c++17 in order to make sure I can use it in my project? I'm using Clang as compiler in my code and the library has been compiled using g++ .
Edit: If I use g++ in both library and my code is there any obstacle in terms of different c++ standards (std11 vs std17)?
Many Thanks,
In general, you should be able to use a C++11 library in C++17 code.
But, you need to remember that C++ does not have a standardized ABI. So the source may be compatible, but any pre-compiled artifacts are likely not.
You have source compatibility, not binary compatibility. This means that - as a rule - you must compile all parts of your project with the exact same compiler. You cannot (as a rule) re-use a library compiled with a different or older compiler with code you compile with a different (or newer) one.
But you should be able to compile that C++11 code with your C++17 compiler (in most cases - there are exceptions).

Undefined reference error to std::string and std::vector class methods [duplicate]

Are there any differences in the linking process between gcc and g++?
I have a big C project and I just switched part of the code to C++. The code isn't using std C++ library yet, so -llibstdc++ isn't needed for now.
The main difference is that (assuming the files are detected as C++) g++ sets up the flags needed for linking with the C++ standard library. It may also set up exception handling. I wouldn't rely on the fact that just because your application doesn't use the standard library that it isn't needed when compiled as C++ (for example the default exception handler).
EDIT: As pointed out in comments you'll have trouble with any constructors (that do work) for static objects as well as not getting virtual function tables (so if you're using those features of C++ you still need to link that library).
EDIT2: Unless you're using C99 specific code in your C project I would actually just switch to compiling the whole thing as C++ as the first step in your migration process.
gcc and g++ are both just driver programs that don't do anything other than calling other programs, so you can use the -v option to see exactly what they do -- what other programs they invoke with what args. So you can see exactly what the difference is between linking with gcc and g++ for the specific version and architecture of gcc that you happen to have installed. You can't rely on that staying the same if you want portability, however.
Depending on what you are doing, you might also be interested in the -### argument
I think that the g++ linker will look for the CPP mangled function names, and it is different from the C ones. I'm not sure gcc can cope with that. (Provided you can explicitly use the C version rather than the C++ one).
Edit:
It should work if you have
extern "C" {
<declarations of stuff that uses C linkage>
}
in your code and the object file has been compiled with g++ -c. But I won't bet on this.

C++11 code/library in non C++11 program

Assume that I compile the code in C++11 (I'll use Lambdas) to ".o" or library ".a".
And I have a program, where I will include previous library and header file, that I can't compile with C++11, but old one ( C++98 ).
Will it compile and work fine?
It will work fine if:
the (public) header doesn't use any C++11 features
the ABI hasn't changed
consult your platform/compiler on this one
no common dependency has changed
as per the GCC document linked by Vaughn Cato, this includes the standard library. Anything that generates different code or object layouts when compiled with C++11, and is used by both library and client may be a problem ... even if it isn't used in the interface itself.
If point 3 is your only issue, you may be able to get around it by compiling a dynamic library (depending on platform a .so, or a .dynlib, or a DLL as Adrian suggests) with all dependencies statically linked internally and not exported. It's a bit hairy though.
Probably not. The reason that name mangling (why the ABI changes) in c++ exists is because incompatibility differences between c++ versions can make code unstable if it will work at all.
If you have code that doesn't compile against c++11, you'll probably have to refactor one of your programs to compile against the other compiler. (Most likely get your old code to compile with the new compiler)
If this isn't an option, you can try and make the c++11 lib a DLL with a C interface or with a COM object interface, but exceptions would stop at that boundary, and if you go the DLL route, you would more than likely want to write a wrapper class to access the c++11 object, so that it acts like an object on your pre c++11 side of the boundary.
One common approach is to provide a C version of the API (extern "C" functions) with objects passed around using opaque pointers. This is more likely to be compatible between languages and compilers.

Any difference in linking with gcc vs. g++?

Are there any differences in the linking process between gcc and g++?
I have a big C project and I just switched part of the code to C++. The code isn't using std C++ library yet, so -llibstdc++ isn't needed for now.
The main difference is that (assuming the files are detected as C++) g++ sets up the flags needed for linking with the C++ standard library. It may also set up exception handling. I wouldn't rely on the fact that just because your application doesn't use the standard library that it isn't needed when compiled as C++ (for example the default exception handler).
EDIT: As pointed out in comments you'll have trouble with any constructors (that do work) for static objects as well as not getting virtual function tables (so if you're using those features of C++ you still need to link that library).
EDIT2: Unless you're using C99 specific code in your C project I would actually just switch to compiling the whole thing as C++ as the first step in your migration process.
gcc and g++ are both just driver programs that don't do anything other than calling other programs, so you can use the -v option to see exactly what they do -- what other programs they invoke with what args. So you can see exactly what the difference is between linking with gcc and g++ for the specific version and architecture of gcc that you happen to have installed. You can't rely on that staying the same if you want portability, however.
Depending on what you are doing, you might also be interested in the -### argument
I think that the g++ linker will look for the CPP mangled function names, and it is different from the C ones. I'm not sure gcc can cope with that. (Provided you can explicitly use the C version rather than the C++ one).
Edit:
It should work if you have
extern "C" {
<declarations of stuff that uses C linkage>
}
in your code and the object file has been compiled with g++ -c. But I won't bet on this.