https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60555
--- Comment #9 from Niall Douglas <s_gccbugzilla at nedprod dot com> --- Transferring over from #86750: --- cut --- Got bitten by this yet again today in Boost.Outcome and the P1031 LLFIO reference implementation, so despite it being already reported at #60555, I'd like to get this fixed already. It's been four years of writing libstdc++ specific workarounds, no fix on the horizon :( This should not fail. It does on libstdc++ 9.0 trunk: ``` #include <cassert> #include <iostream> #include <system_error> bool test() { return std::error_code(EEXIST, std::system_category()) == std::errc::file_exists; } int main() { std::cout << test() << std::endl; assert(test() == true); return 0; } ``` https://wandbox.org/permlink/jYpIIMlXKJ4zX3ud Jonathan says in #60555 'The standard also says "What constitutes correspondence for any given operating system is unspecified."' for mapping POSIX error codes onto generic codes. However the full text for system_category() is actually: ``` If the argument ev corresponds to a POSIX errno value posv, the function shall return error_condition(posv, generic_category()). Otherwise, the function shall return error_condition(ev, system_category()). What constitutes correspondence for any given operating system is unspecified. [ Note: The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX errno value. Thus implementations are given latitude in determining correspondence. — end note ] ``` So what the standard means here is that on POSIX systems, system_category is by definition a superset of generic_category. All generic_category codes are guaranteed to map onto system_category if the system is POSIX compliant. The reverse is not the case, because the POSIX implementation may have proprietary error codes which have no valid mapping in generic_category. My test program above compares a system category error code of EEXIST - which is a POSIX error code - to the generic code errc::file_exists. This is supposed to return true. See the equivalent Boost.System based test example https://wandbox.org/permlink/FQ9u6DtTkw2Uno1A and it indeed works correctly. Windows, despite not being POSIX, also gets this right: ``` #include <cassert> #include <iostream> #include <system_error> #include <windows.h> bool test() { return std::error_code(ERROR_FILE_EXISTS, std::system_category()) == std::errc::file_exists; } int main() { std::cout << test() << std::endl; assert(test() == true); return 0; } ``` Please fix libstdc++.