11

C++0x has two predefined error_category objects: generic_category() and system_category(). From what I have understood so far, system_category() should be used for errors returned by the operating system, and generic_category() should be used for the generic values found in std::errc, which correspond to errno values.

However, what should be done on Unix-like systems, where errno values are the errors returned by the operating system? Should I use system_category() (which would be wrong on non-Unix-like systems, needing an #ifdef), or should I use generic_category() (which would be wrong on Unix-like systems for non-standard errno values)?

CesarB
  • 43,947
  • 7
  • 63
  • 86

2 Answers2

2

You are meant to report errors from OS (any one, including POSIX-based OSes such as Unix) using system_category() as C++ standard library functions do - see the quote from C++11 standard below:

17.6.5.14 Value of error codes [value.error.codes]

1 Certain functions in the C++ standard library report errors via a std::error_code (19.5.2.1) object. That object’s category() member shall return std::system_category() for errors originating from the operating system, or a reference to an implementation-defined error_category object for errors originating elsewhere. The implementation shall define the possible values of value() for each of these error categories. [ Example: For operating systems that are based on POSIX, implementations are encouraged to define the std::system_category() values as identical to the POSIX errno values, with additional values as defined by the operating system’s documentation. Implementations for operating systems that are not based on POSIX are encouraged to define values identical to the operating system’s values. For errors that do not originate from the operating system, the implementation may provide enums for the associated values. —end example ]

Community
  • 1
  • 1
PowerGamer
  • 2,106
  • 2
  • 17
  • 33
  • 2
    Well "from the OS" is not so clear as it sounds. `errno` comes from the libc on Unix (which is part of the OS). On Windows, `errno` comes from a C runtime which is not necessarily part of the OS. And you cannot use `system_category` for `errno` anyway on Windows, as this should be reserved for native windows errors. However if you do a `fopen`, in both case you would like to handle `errno` the same. – ysdx Feb 23 '16 at 16:12
1

You should not use system_category unless you are in fact the operating system (or reporting an error from an OS-specific function). The category describes where the error originates from, not necessarily what the error code means. So it is perfectly legitimate to have the set of possible error codes from system_category be the same as generic_category.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 2
    Let's see if I am getting it: I should always use `system_category()`, since the `errno` value I have came from an operating system function (or from a function which called an operating system function, or from a function which called a function which called...). But what to do on Win32, since `system_category()` would be for `GetLastError()` values, and the C library functions would report the errors in `errno`? – CesarB Sep 25 '11 at 01:17
  • @CesarB - That sounds like the exact opposite of what Nicol Bolas wrote. :) If the errno was already set by a function you called, why mess with it? But if you do need to mess with it, Nicol is advising you to use `generic_category`. – Marc Sep 27 '11 at 17:35
  • 1
    @Marc: I am calling a function which sets errno (for instance `epoll_ctl` or `open`), and I want to throw a `system_error` (wrapping the errno) in case of error. – CesarB Oct 02 '11 at 16:50