If you compile this program with GCC 4.9, but you have libstdc++ version 5.1 installed on your system. (E.g., this is the case for me because I'm using Debian unstable). #include <system_error> int main() { std::error_code x = make_error_code(std::errc::no_such_file_or_directory); std::error_condition e = std::errc::no_such_file_or_directory; return x == e; } Then running it will return 0 instead of 1, like it should, (and did, with libstdc++ 4.9 installed). So, the thing to note, is that both "x" and "e" here have a category() of _ZSt16generic_categoryv() as their category instance -- NOT _ZNSt3_V216generic_categoryEv(), because it was built against the old headers. (This seems to be as intended.) Going through the calls, first we have this from libstdc++-v3/include/std/system_error: inline bool operator==(const error_code& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category().equivalent(__lhs.value(), __rhs) || __rhs.category().equivalent(__lhs, __rhs.value())); } which calls, from libstdc++-v3/src/c++11/compatibility-c++0x.cc: bool error_category::equivalent(int __i, const error_condition& __cond) const noexcept { return default_error_condition(__i) == __cond; } which calls, from the same file: error_condition error_category::default_error_condition(int __i) const noexcept { if (*this == system_category()) return error_condition(__i, _V2::system_category()); return error_condition(__i, _V2::generic_category()); } which returns a _V2::generic_category() object. Oops. Now we're in big trouble! Then, back to error_category::equivalent, where it calls, from libstdc++-v3/include/std/system_error: inline bool operator==(const error_condition& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category() == __rhs.category() && __lhs.value() == __rhs.value()); } Which fails, because __lhs.category() is the V2 generic_category, and __rhs.category() is the "V1" generic_category.
You always need to use the libstdc++ that is bundled with the compiler.
(In reply to Andreas Schwab from comment #1) > You always need to use the libstdc++ that is bundled with the compiler. Actually that is true but that does not make this bug a valid bug. What is mentioned is c++11 abi breaks between 4.9 and 5. So this bug is still invalid but a slightly different reason. From now (5), gcc will no longer break the abi.
Indeed. Before gcc-5 it was never supported to combine C++11 objects compiled with different major versions. The whole point of calling C++11 support experimental was that we reserved the right to make incompatible changes to the C++11 features, otherwise you'd be forever stuck with the partial C++0x support added around the gcc-4.4 timeframe.
The problem actually is Debian has gcc-4.9 as default compiler, and the libstdc++ provided in testing is from gcc-5.
Sorry, please try again. Andreas Schwab: I did compile it with the libstdc++ that came with the compiler -- and then I upgraded the binary libstdc++.so to the newer one that came with gcc 5. And it broken. Thus the report of breaking binary compat. (It also happens with new compiles in Debian because of what Gianfranco says) Andrew Pinski: The *one and only purpose* of the file libstdc++-v3/src/c++11/compatibility-c++0x.cc is to provide binary compatibility for c++11 binaries compiled against older libstdc++ versions, and now running against a newer one. If libstdc++.so.6, version 5.1, is not supposed to work properly with c++ binaries compiled by the 4.9 compiler, it should not be providing these compatibility symbols at all. Since it does provide them, there is clearly intent to provide compatibility so, it ought to work. Or they should be deleted...
(In reply to James Y Knight from comment #5) > The *one and only purpose* of the file > libstdc++-v3/src/c++11/compatibility-c++0x.cc is to provide binary > compatibility for c++11 binaries compiled against older libstdc++ versions, > and now running against a newer one. It ensures they will still link. > If libstdc++.so.6, version 5.1, is not supposed to work properly with c++ > binaries compiled by the 4.9 compiler, it should not be providing these > compatibility symbols at all. I would prefer that, but it's not our policy. > Since it does provide them, there is clearly intent to provide compatibility I didn't realise you were the maintainer and knew what's supposed to work. Oh wait, you're not :-)
If you can provide a patch that makes it work without any unwanted side effects then I'll certainly look at it, but mixing versions for C++11 code is unsupported, and so I'm not going to spend my time trying to make it work.
Created attachment 35708 [details] Compare old and new categories This fixes this specific testcase, but not all cases (if you compare error_condition objects created in different translation unit compiled with different GCC versions then whether it works depends on which error_condition is on the left-hand side).
What good is having special code to allow linking compatibility, if the program then can't work anyways? Isn't that anti-useful? > I didn't realise you were the maintainer and knew what's supposed to work. No, of course...I'm only a user.... > If you can provide a patch I'm not certain, but it seems like probably the old-ABI error_category::default_error_condition(int) ought to just return an error_condition also with the old ABI, instead of the new one? CC'ing debian's gcc maintainer, because the stated lack of desire for compatibility between libstdc++ version 5, and g++ 4.9 seems like it's probably something he wasn't aware of when upgrading.
Oops, actually cc'ing doko this time (hopefully.)