categories and standard/system error codes

I have to admit to a bit of surprise at the confusion regarding <system_error> given Chris summarised exactly how it works at http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-1.html and I personally find the C++ standard text above perfectly clear. But to summarise in very succinct words:

If on POSIX:

generic_category => POSIX standard errno space

system_category => Local POSIX errno space (usually extends POSIX with proprietary errno codes). Use strerror() to expand codes into string descriptions returned by message().

In practice on POSIX both implementations are the same underneath and map the native errno space.

If on Windows:

generic_category => POSIX standard errno space which is returned by various POSIX emulation functions in the MSVCRT like fopen() etc

system_category => The Win32 GetLastError() space. Use FormatMessage() to expand codes into string descriptions returned by message().

How to use <system_error> portably

std::error_code ec;
#ifdef _WIN32
if((HANDLE)-1 == CreateFile(...))
  ec = std::error_code(GetLastError(), std::system_category());
#else
if(-1 == open(...))
  ec = std::error_code(errno, std::system_category());
#endif
// To test using portable code
if(ec == std::errc::no_such_file_or_directory)
   ...
// To convert into nearest portable error condition (lossy, may fail)
std::error_condition ec2(ec.default_error_condition())

Other thoughts:

Some commentators have said that <system_error> is poorly designed and shouldn’t be used. This is simply not true, it’s pretty optimal given the C++ 03 idiomatic practice of the time of its design, it generates very tight high quality fixed latency code on all major STLs except Dinkumware’s. It’s user extensible to any arbitrary error code system, and standardises unifying into a single system disparate third party library error handling.

It is true it would look quite different today had constexpr global variables been available at the time of its design, and maybe that might get rectified in a C++ standard coming after 17. But if you are a programmer who needs to move around error codes from third party libraries without losing information through code not written to know about those third party libraries, then <system_error> is an excellent solution.

Consider it as similar to the virtual keyword for third party library error code handling – it erases the need for code transporting third party codes from needing to understand those codes. If you have that problem in your code base – and most large code bases do – then absolutely you should be using <system_error> instead of whatever error code mapping or translation system you’re currently using.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)