|
|
Log in / Subscribe / Register

GCC5 and the C++11 ABI (Red Hat developer blog)

A post at the Red Hat developer blog looks at some of the changes that are coming with GCC5. Support for the C++11 standard means that some standard library classes need to change their ABI, notably std::basic_string and std::list. The post looks at how the change has been handled and what programmers need to do to deal with the changes. "The last time G++ went through an ABI change, back in the 3.x period, we changed the soname of libstdc++, which was widely regarded as a mistake. Changing the soname caused a lot of pain but is not sufficient to deal with changes in symbol ABIs: if you load multiple shared objects that depend on different versions of the library, you can still get clashes between different versions of the same symbol. So the plan for this ABI change has been to leave the soname (and the existing binary interface) alone, and express the new ABI using different mangled names."

to post comments

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 5, 2015 23:45 UTC (Thu) by cesarb (subscriber, #6266) [Link] (15 responses)

I wonder how this will work in Fedora 22. From what I've read (http://www.phoronix.com/scan.php?page=news_item&px=Fe...) Fedora won't do the traditional mass rebuild this time.

Suppose you have C++ library libfoo, which is used by C++ library libbar, and both were build before GCC 5 became the default compiler. An update is released for libfoo, which means it'll be rebuilt with GCC 5. Now we have an ABI mismatch, and libbar won't load due to missing symbols (since the mangled name for functions using std::string parameters ends up being different).

I also wonder how many kilobytes this is going to add to symbol tables...

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 0:33 UTC (Fri) by JoeBuck (subscriber, #2330) [Link] (14 responses)

From the article: Users that depend on third-party libraries or plugin interfaces that still use the old ABI can build their code with -D_GLIBCXX_USE_CXX11_ABI=0 and everything should work fine.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 2:41 UTC (Fri) by mcatanzaro (subscriber, #93033) [Link] (13 responses)

As you've probably guessed, this is what is in fact what has been done for F22. After F22 branches off of rawhide, Fedora will start using the CXX11 ABI.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 7:39 UTC (Fri) by mbunkus (subscriber, #87248) [Link] (9 responses)

As an application developer requiring C++11 or higher for compilation, does that mean that I have to add that define when compiling on F22? If so this is somewhat ridiculous. Now I have to start adding configure checks for specific distro versions?

Looks like I need to install Rawhide and experiment with it somewhat.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 9:20 UTC (Fri) by javispedro (guest, #83660) [Link] (5 responses)

You can still use C++11 with the older ABI (like you're probably doing now), it's just that you won't get some of the new features that require ABI changes, like constant time std::list::size.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 9:34 UTC (Fri) by mbunkus (subscriber, #87248) [Link] (4 responses)

I'm not concerned about whether or not I can still use the old ABI. I would like to know whether or not I, as an application developer, have to add -D_GLIBCXX_USE_CXX11_ABI=0 on Fedora 22. If they don't recompile their packages for the 22 release then e.g. wxWidgets (which usually isn't even built with -std=c++11) will still use the old ABI, and unless I tell g++ 5 otherwise it would use the new one leading to… what exactly? Errors during linking? When starting the application? Runtime crashes?

And if I do have to add that define: I don't really have an idea how to build a proper configure check for that. Sure, I could simply create a list of distributions and versions and try to detect which distro/version configure is executed in, but that seems fragile.

The official announcement from the gcc developers is clear enough for me: if all the libraries you use have been re-built with gcc 5 then you don't have to worry about a thing. Great. Fedora's choice not to re-compile makes the situation a lot murkier for me.

Unfortunately current Rawhide doesn't carry gcc 5 at the moment, so I cannot test it for myself yet.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 9:57 UTC (Fri) by javispedro (guest, #83660) [Link] (3 responses)

Nothing will happen. It will be as it is now: no compatibility is guaranteed between C++11 and C++98, but it works in practice (TM).

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 10:14 UTC (Fri) by mbunkus (subscriber, #87248) [Link] (1 responses)

I'm sorry to be nitpicky, but that doesn't answer my question at all. This is how the situation looks to me at the moment:

- The existing libraries (e.g. wxWidgets) have been compiled with gcc 4.x with the »old« ABI.
- The compiler that will end up in Fedora 22, gcc 5.x, will use a new ABI by default (and offer both the old and the new ABI in the libraries it bundles, libstdc++).
- Any application that is compiled on Fedora 22 with gcc 5.x without any special flags will use the new ABI.

So my application includes wxWidgets' headers and libstdc++ headers, and due to gcc being in »new ABI« mode I'd expect linking errors to occur. Or something worse.

Unless I add -D_GLIBCXX_USE_CXX11_ABI=0.

Maybe I should install gcc 5 somewhere and give it a try…

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 12:02 UTC (Tue) by jwakely (guest, #60262) [Link]

> - Any application that is compiled on Fedora 22 with gcc 5.x without any special flags will use the new ABI.

No. It will use the old ABI, because GCC in F22 is configured to use the old ABI by default. So no linker errors.

It is expected that in F23 using gcc 5.x without special flags will use the new ABI, but in F23 wxWidgets will have been recompiled using the new ABI, so still no linker errors.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 12:55 UTC (Tue) by jwakely (guest, #60262) [Link]

When c++98 and c++11 compatibility has been broken it has been considered a serious bug and fixed, e.g. in gcc 4.7.0 passing a std::pair by value was done differently in c++98 and c++11 modes, due to a non-trivial move constructor. That was fixed as a critical bug.

The rule is that you can combine c++98 and c++11 objects compiled with the same version of GCC, but cannot combine c++11 objects compiled with gcc 4.x with c++11 objects compiled with gcc 4.y, and the intention is that from gcc 5 onwards even that restriction will go away.

The reason that the choice of std::string ABI is controlled independently from the -std=c++NN option is precisely to guarantee compatibility between -std=c++98 and -std=c++11 code.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 12:50 UTC (Fri) by mcatanzaro (subscriber, #93033) [Link] (1 responses)

I don't think you need to worry about this, unless you rely on the brand-new standard-compliant behavior from std::string or std::list. See https://lwn.net/Articles/632183/

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 12:54 UTC (Fri) by mbunkus (subscriber, #87248) [Link]

Ah yes, that's what I had hoped for. Thanks.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 11:58 UTC (Tue) by jwakely (guest, #60262) [Link]

> As an application developer requiring C++11 or higher for compilation, does that mean that I have to add that define when compiling on F22?

No.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 9:29 UTC (Fri) by cesarb (subscriber, #6266) [Link] (2 responses)

Let's see if I understood: Fedora 22's gcc packages have been configured to set -D_GLIBCXX_USE_CXX11_ABI=0 by default, and Fedora 23 (after the mass rebuild) will use the upstream default?

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 12:45 UTC (Fri) by mcatanzaro (subscriber, #93033) [Link] (1 responses)

Looks like it. For now it's configured with --with-default-libstdcxx-abi=c++98

http://pkgs.fedoraproject.org/cgit/gcc.git/tree/gcc.spec#...

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 11:51 UTC (Tue) by jwakely (guest, #60262) [Link]

Yes, that's correct.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 0:40 UTC (Fri) by xnox (subscriber, #63320) [Link] (2 responses)

Is this *new* break, or the same one as in gcc-4.9? As far as I remember, string and list c++11 abi was broken in 4.9 and albeit the c++11 standart was not default in gcc 4.9 some users got bitten, e.g. those that compiled or required software with that standard level enabled did soname bumps.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 1:40 UTC (Fri) by ncm (guest, #165) [Link]

It's not wrong to bump your soname. But it appears it's not strictly necessary. I expect it probably is a lot more work if you don't. If so, then thank you to the G++ team for doing the extra work.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 11:55 UTC (Tue) by jwakely (guest, #60262) [Link]

> As far as I remember, string and list c++11 abi was broken in 4.9

No, that is not true. You might be thinking of the std::list::size() change in 4.7.0 and 4.7.1, but that incompatibility was fixed for 4.7.2 and later versions. There has been no std::string ABI change until now.

Mistake?

Posted Feb 6, 2015 1:34 UTC (Fri) by ncm (guest, #165) [Link]

"In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move." Seems familiar.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 4:19 UTC (Fri) by butlerm (guest, #13312) [Link] (5 responses)

I understand why the name mangling needs to be changed, but surely keeping the soname the same requires compiling in certain functions with names mangled for both ABIs?

It seems like it would be a lot simpler to change the soname and provide a compatibility package for the version of the library with the old ABI. Unless of course you want to go out of your way to avoid having two different versions of the same library loaded into some processes, which I imagine might cause a few problems besides inefficiency.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 9:18 UTC (Fri) by javispedro (guest, #83660) [Link] (3 responses)

I suspect that using namespaces has the benefit that the compiler will be able to detect e.g. trying to pass a v2 string on a function that actually takes a v1 string. Unlike with sonames, where you'd be able to easily do so (and crash accordingly).

On the other hand, it also means that libstdc++.so will now contain v1 and v2 symbols for all of string, list and the related classes, increasing bloat.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 6, 2015 21:24 UTC (Fri) by jgg (subscriber, #55211) [Link] (1 responses)

There aren't going to be a lot of symbols for that kind of stuff. Without a list of exactly what they changed it is hard to tell. Presumably someone looked at this.

The problem with the soname migrations in the past was the new soname tried to re-use the old symbol names with different functionality. That was a disaster. The elf symbol namespace is effectively global in too many cases, so things didn't work.

Churning the symbol names and soname together avoids most problems.

The really clever thing about this tags system is that it extends beyond libstdc++ - if my own lib exports foo(std::list<thing> bar) then the tag mangling will cause it to not link to apps built with the new abi even though this has nothing to do with libstdc++.

Hopefully clang picks this up ASAP.

The C side should pick it up too.. much better than symbol versions alone.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 12:28 UTC (Tue) by jwakely (guest, #60262) [Link]

> There aren't going to be a lot of symbols for that kind of stuff.

Sadly far more than you'd think. The obvious ones are std::stringbuf and std::ostringstream etc, which need new versions that use the new string. Less obvious is that a number of locale facets use std::string in their public API (e.g. std::numpunct::falsename() and the corresponding virtual function std::numpunct::do_falsename()) so as well as std::__cxx11::string and std::__cxx11::list it's also necessary to define std::__cxx11::numpunct, std::__cxx11::num_get and std::__cxx11::time_get and a number of other facets. And then std::locale needs to contain both versions of those facets, so that e.g. std::has_facet<std::num_get<char>> returns true for both versions.

> Without a list of exactly what they changed it is hard to tell. Presumably someone looked at this.

In excruciating detail!

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 12:06 UTC (Tue) by jwakely (guest, #60262) [Link]

> I suspect that using namespaces has the benefit that the compiler will be able to detect e.g. trying to pass a v2 string on a function that actually takes a v1 string. Unlike with sonames, where you'd be able to easily do so (and crash accordingly).

Right.

> On the other hand, it also means that libstdc++.so will now contain v1 and v2 symbols for all of string, list and the related classes, increasing bloat.

Also right.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 10, 2015 12:13 UTC (Tue) by jwakely (guest, #60262) [Link]

> surely keeping the soname the same requires compiling in certain functions with names mangled for both ABIs?

Right.

> It seems like it would be a lot simpler to change the soname [...]

Isn't that covered by the quote taken from the blog post?

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 7, 2015 9:05 UTC (Sat) by quotemstr (subscriber, #45331) [Link] (2 responses)

We wouldn't have this problem if ELF didn't mash all symbols together into a single global namespace. On many other systems, it's possible for two versions of the same library to coexist peacefully in the same process.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 7, 2015 12:34 UTC (Sat) by cesarb (subscriber, #6266) [Link] (1 responses)

> On many other systems, it's possible for two versions of the same library to coexist peacefully in the same process.

That leads to a different problem. Suppose you have two versions of the standard C++ library, with different implementations for std::list; for instance, one of them has an extra field for the list size, while the other uses a smaller structure and computes the size every time it's needed.

Now suppose you have a third library, with an API which uses std::list; it could have for instance a function which receives a list of widgets. Your program uses this third library.

This will only work if both your program and the third library are linked against the *same* version of the standard C++ library. And even if they are now, a new version of the third library (with an unchanged API) could be linked against the other version of the standard C++ library.

One of the "other systems" is Microsoft Windows, where it's common to have several versions of the C library running in the same process at the same time. If you for instance allocate memory from one C library and try to release it using another C library, it won't work correctly. The same applies to FILE structures and even file descriptors (Win32 uses handles internally, the file descriptor table is within the C runtime).

The OpenSSL library has a workaround (ms/applink.c) where it calls an exported function on the *executable*, which returns a table of pointers to functions like fread or fwrite; that way, it can always use these functions from the executable's C runtime. This workaround is not needed on systems with a flat namespace, or on systems where it's not possible for two versions of the C library to coexist in the same process.

GCC5 and the C++11 ABI (Red Hat developer blog)

Posted Feb 8, 2015 16:14 UTC (Sun) by mathstuf (subscriber, #69389) [Link]

All those problems make sense and I can see the logic. Also, those other platforms don't support symbol versioning and the two problems are (roughly) isomorphic, just that symbol versioning is very uncommon.

Anyways, a little OT, but what *I* want (and this may be an implementation bug, not an ELF bug; not sure) is when RTLD_LOCAL is used to open library A which links to library X and then I do the same for library B which also links X is for B to not fail to load because X is now private to A and only A. Basically, don't make RTLD_LOCAL transitive.


Copyright © 2015, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds