Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::generic_category() is useless?

Tags:

c++

c++11

A quote from C++11 standard:

19.5.1.5 Error category objects [syserr.errcat.objects]

 const error_category& system_category() noexcept;

4 Remarks: The object’s equivalent virtual functions shall behave as specified for class error_category. The object’s name virtual function shall return a pointer to the string "system". The object’s default_error_condition virtual function shall behave as follows:

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 ]

In other words the code below on some OSes may not work because the system_category().default_error_condition() did not do the proper mapping to generic_category() condition (which is fully allowed by the standard):

try
{
    // do some file IO
}
catch(const std::system_error& e)
{
    if(e.code() == std::errc::permission_denied) //...
}

The only solution would be to implement your own custom replacement for generic_category() with mapping for all the OS codes you require (for all the OSes you need).

enum my_errc { /*...*/, access_denied };
class my_generic_category : public std::error_category
{
    virtual bool equivalent(const error_code& code, int condition) const noexcept
    {
#ifdef _WIN32
        if(code == std::error_code(ERROR_ACCESS_DENIED, std::system_category())
            return condition == my_errc::access_denied;
#elseif SOME_OTHER_OS // ...
    }
// ...

And then use your own category instead of generic_category:

catch(const std::system_error& e)
{
    if(e.code() == my_errc::access_denied) //...
}

So what's the point in having std::generic_category() at all then?

like image 496
PowerGamer Avatar asked May 03 '26 16:05

PowerGamer


1 Answers

The question should be asked: Are you attempting to write code that is absolutely positively not compiler specific or are you ok with writing some code knowing that it will require some specific compiler or compiler family?

The standard is there to tell you how to do the former.

While it is a good rule of thumb to write code to work on all compilers (at least on those compilers that follow the standard well enough) sometimes this will mean that you'll be reimplementing some things that are already implemented by the implementation of the specific compiler/library.

like image 55
v010dya Avatar answered May 07 '26 10:05

v010dya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!