Should I use system_category or generic_category for errno on Unix?
Asked Answered
S

2

13

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)?

Santiagosantillan answered 25/9, 2011 at 0:24 Comment(2)
After reading the answers I am still unsure what to use.Lovely
@robert: <system_error> is a convoluted, over-designed mess. How to use that properly? Nobody knows ... (see this thread).Firing
M
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 ]

Morey answered 3/1, 2015 at 22:1 Comment(1)
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.Konopka
W
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.

Wendel answered 25/9, 2011 at 0:48 Comment(3)
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?Santiagosantillan
@Santiagosantillan - 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.Solute
@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.Santiagosantillan

© 2022 - 2024 — McMap. All rights reserved.