std::string build issues across gcc 5.0 boundary

In moving to the 5.0 versions of the gcc compiler/linker, there were C++11-standard driven changes to string libraries which forbid Copy-On-Write strings and requires lists to keep track of their size.

As a result, there is now a compile macro _GLIBCXX_USE_CXX11_ABI which can be 1 or 0.

As I do builds on Linux flavors/machines some of which have < 5.0 compilers installed, ie. gcc -v returns < 5.0, and some > 5.0, I am encountering broken linkages, where I get undefined reference to someclass::somemethod and sometimes it says [abi:cxx11] in the error description from the linker.

There also seems to be some issues with std::vector.

I would have guessed that simply defining _GLIBCXX_USE_CXX11_ABI=0 in all translation units of the build would have solved the problem. But it does not solve the problem.

Is it possible that if the libraries which are in my version of gcc which on the machine in question is version 5.4 were built with the above dual abi flag = 1, that it will never work? Or should I be able to build with the flag set to 0?

For the meantime, I guess I will have to change my interfaces - there are only a few that I need to change, so I can live with this for a week.

Just curious if I fail to understand the dual ABI issue - which to me, means that since they are in different namespaces (ie. the names are totally different due to the extra cxx11 tag part) and since the libraries contain both sets of code - the OLD and the NEW, then this SHOULD be a piece of cake. I just turn on the old stuff by setting the flag = 0, and the compiler and linker should give me those versions.

The problem right now is I'm not observing this - the link fails unless I make sure any name-mangled names are not having string on return. I know it's a little weird to return strings but I am not one to not want a real object on return that knows it's size. For now, I'll have to return char *.

I may need to include extern "C" and other name-mangling issues as I have a class that contains methods and even if the methods do NOT contain any std stuff, I am getting unresolved references. There is something else weird in my project right now. Normally, I would compile with g++ if I am using C++ and gcc if I am not and in that case, I might need some extern "C" over some headers. There is some issue that crept into my builds on gcc > 5.0 compilers (it's not necessarily a dual ABI issue, I was just suggesting that it might be). Hmm.

I am also searching and searching to make sure a header isn't being picked up that's the wrong one.
Last edited on
It's beginning to look like any class that I have defined in my library that uses inheritance leads to unresolved references on the gcc > 5.0 machine. If I define a class and don't inherit from something, I can use the class's methods. And I can use an object of a class that uses inheritance as long as I don't call any of it's methods.

This is totally bizarre.
I suggest you consider statically linking the standard library and seeing if that fixes your issues.

The following link may also be useful: https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html

Hi, thank you for your suggestion. I tried to statically link in stdlib.a etc.., and it did not help.

I then just kept experimenting with coding of Foo, Bar with simple methods until finally I began to have success if I coded the method only in the .h file.
So there is some issue with the .cpp file that I'm using - the < 5.0 compiler doesn't mind it if I do that, but the > 5.0 compiler DOES. Strange. So at least for the next day, I guess I'll just move all of my code over to the .h file. It's only about 100 lines.

Just to elucidate a little: I am simply putting some C API calls in one file, and some small classes in another file, and then packaging them into a static library using ar -cvr etc..

I will try your suggestion once more though as I believe I made a mistake when I tried it (just a simple typo when I put the stdlib.a in my link).

Anyway, I hope in 20 minutes to at least have my executable built. I will then keep restructuring all the classes, std template, c code better and better, and maybe things will clean up.
Hi, thank you for your suggestion. I tried to statically link in stdlib.a etc.., and it did not help.

Don't you mean libstdc++ if you're using the C++ compiler? Also are you properly qualifying those C API calls with extern "C"?

Is there a reason you're still using g++ version 5 instead of one of the more current versions such as g++ 7?

Since you seem to be trying to mix C and C++ you may be interested in this:
https://isocpp.org/wiki/faq/mixing-c-and-cpp

Sorry, my post is a bit open-ended. I was thrown two curve-balls today and just got fooled.

#1 curve) The issue that you suggest looking into wiki on which I've already dealt with to a large extent by using extern "C" in proper and intelligent ways and it works fine when the gcc < 5.

#2 curve) An hour ago, I simply took all of my C++ code and put it into the header file, and now everything compiles and runs fine. But there is a very minor (NEW) issue. The permissions on my dev directories show root as owner. I log in not as root and I honestly don't ever remember setting up a root account. To make a long story short, I normally only have to type sudo before certain of my commands. And there is one last one that I never before had to type sudo to get it to run (until today). But today I had to do this. So something has changed at the operating system level without my knowing it. The permissions are root. I should change them to my login account. But I can live with this just by using sudo everywhere.
So now when I make an open call open(path, mode) for this one call that I used to get for free (not needing sudo), it gives permission denied and it forces me to run the program as sudo ./program. I never had to do this before, that's all. I would have been happier if some process hadn't changed something without my knowing.

So in response to your suggestions, I will do some more splitting up of my files even finer to possibly isolate what is messing up my c++ file, but not my .h header declarations file, which I'm now using as a cpp file (temporarily). And I'll check out that wiki later today. As for g++7, I will look into it when I can. But I want my code to compile on older compilers if possible.
Make sure your header files don't contain any executable code (other than template code).

And remember that there was a breaking ABI change somewhere arround gcc 3.4.

Also are you compiling the "library" with the same compiler tool chain that you're using to compile the program?

I use the same compiler for the static lib and executable (user of the static lib) builds. On fatdog, I use 4.8.something and on Mint I use 5.4.something.

Today, I decided to stick with my code in a header file until I can troubleshoot the issue as I had a functional issue in my code to fix, which is now fixed.

It was 12 hours of work, so my backing my code out of my header back into my .cpp file as you suggest will have to wait until tomorrow.

All in all, the code is running perfectly now, much, much better than as of yesterday. I had not run it on Mint in over a week but it's running nice.

I haven't even come up with scripts such as ./configure, make, and make install yet, I just compile and link from within my editor or at the command prompt.

All the string and vector stuff is working perfectly - it's just the "why in the .h" issue. It's nice having the high-level abstraction of a string class which is basically like a vector and it knows it's size and can resize and also be able to get at the chars if I need to hence my having more OO-oriented string handling. I favor neat, readable code over obsessive-compulsive (how many copies did you make?). Ultimately, the oo method will be every bit as efficient. and methods much more readable. It's nice because my code now has all kinds of delegations from my GUI to worker ants doing the processing. Some of the methods are one line even with extensive validations I'm doing.

Thanks for the advice.
Also note that g++ 4.8.1 has complete C++11 support but lacks many C++14 features that are available in g++ 5.4. Notable differences are that 4.8 supported VLA as part of the standard and this support is removed in 5.0. If you're using any C++14 features I recommend you migrate to at least g++ 6 since this version is C++14 feature complete. If you want C++17 features you should get the most recent version of g++ available.

IMO, with the compilers you're dealing with you should be sure to specify the desired standard and you should avoid the gnu hacks and use one of the following --std=c++98, --std=c++11, or --std=c++14 (I don't recommend C++17 with the compiler versions you indicated, in fact you may want to stick with C++11 for those versions since it should be supported by both compilers).

Just thought I'd update my somewhat oddly-created thread with some new information.

After getting some unresolved references on a new class I'd defined, I thought I'd simply run the command: nm mylib.a

on my library to look at the decorated/un-decorated names of the function calls to see if I could simply match this on importing stuff as a quick fix for the problem that would not involve compile flags, or a complete rebuild of the entire set of libraries on the Linux OS. Voila! That's when I noticed that there were no function names from the classes I'd defined in the last 4 days. No wonder - I had accidentally deleted out the .o of the new classes in my link. So it wasn't really an issue of the string vs. __cxx11::string, I had simply failed to link in an entire object module. Frankly, my compiler and linker don't seem to really care about which of these strings I use. So I had been running my code somewhat fortuitously by stuffing things in a header when I COULD have simply been linking in my .cpp's .o file. So now everything is building with either compiler fine. On the machine with the 4.8.xx compiler, I had NOT accidentally deleted one of my object files from my g++ link call, which explains why there were never any unresolved references.

I don't know why I had deleted a .o from my g++ link call on the 5.4.xx machine - just probably modifying some flag some time and accidentally did it.

LOL.
Topic archived. No new replies allowed.