https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438
Bug ID: 66438 Summary: libstdc++ 5.1 broke binary compat with old code using std::error_category Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- 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.