I appreciate that the special meaning of 0 may be undesirable
It's not just undesirable. It's incorrect. The present design precludes any third party error code domain which does not treat 0 as being success, or which treats values in addition to 0 as success, from being wrapped into an error code. And that was one of the prime motivations behind the original design: to wrap existing third party error code domains, often from legacy C libraries, into C++.
, but having a virtual function call overhead whenever one wants to test if the error_code has a success value seems a too high price for that. I don't want to be paying that price in my Linux programs, sorry.
You have a completely misguided estimation of relative costs here. This argument has no basis in empirical reality. Also, it's prejudiced as well. Your use case never sees more than one success value, so you fret about the "extra cost" of an indirect jump for testing that. But in my use case in AFIO I have to insert extra if statements to work around the fact that there are multiple success values possible from calls to the NT kernel. So I'm getting loaded with overhead so you don't have to be, and given the whole original design purpose of Boost.System which was to wrap C error code domains into better C++, I don't find that fair. (The reason I quote "extra cost" of an indirect jump is that there is no extra cost on any recent out of order CPU including ARM and Intel. It's literally zero cost in the hot cache case because it's been speculatively dereferenced, there isn't even a pipeline stall. Haswell and later can even make a virtual function call immediately calling a virtual function zero overhead in the hot cache case, the speculative execution reaches two levels down most of the time in most circumstances)
It would still return a reference, just as now. You would check for internal nullptr, if so return a static null_category.
Why check in the first place if you could initialize the pointer to the global instance of the category?
It cannot currently be done portably on all current compilers. Peter's LWG defect resolution - as far as I understand it - needs some extra compiler magic in the form of Immortalize. Without that one cannot guarantee a single instance of a category anywhere in the process. And that is a hard requirement by the current C++ standard.
But it cannot elide the potential call to an extern function, the function which retrieves the error_category&. And therefore must emit code, just in case the system_category might be fetched.
I don't think the current standard requires an external function call. The default constructor can obtain the pointer to the global category instance directly, if it is exported. `system_category()` can be an inline function as well.
You are incorrect. The C++ standard imposes a hard requirement that all error categories cannot - ever - have more than one instance in a process. That rules out inline sources of error categories. If you don't implement that, including in custom error categories, bad things happen, specifically error condition testing stops working right.
I don't have an estimate on how widespread custom error categories are, but I surely have a few. I know that several Boost libraries define their categories (namely, Boost.Filesystem, Boost.ASIO, Boost.Beast, Boost.Thread come to mind). Searching on GitHub[1] finds a few examples of custom categories (with a lot of noise from the comments though). Judging by that, I wouldn't say that custom categories are rare.
But they are however rare enough, and moreover, extremely easy to upgrade. My intended proposal for WG21 is that when you compile code with C++ 23 or later, the new string_view signature takes effect. If you compile with C++ 20 or earlier, the string signature remains. Breaking API has been done before in the C++ standard library, hence the need for standard version switches.
[1]: https://github.com/search?l=C%2B%2B&q=error_category&type=Code&utf8=%E2%9C%93
In fairness, more than I expected.
But I currently believe that code other than custom error categories _won't_ break. We are changing the API in ways that I would be very, very surprised if much real world code out there even notices.
Code that relies on a specific error category in the default-constructed `error_code` will break.
I've never seen such code, and even if it is doing that, it should stop doing so. system_category depends exclusively on the host OS. Code which behaves like that would not be portable.
I don't think I remember an intentional major breakage of API without a deprecation period and a clear migration path. Such breakages are typically introduced as new libraries that live alongside with the old ones.
This is hardly a major break. Minor break I can agree with. Remember there will be a macro lets you switch on the old API. Remember the string_view stuff only turns on if being compiled with C++ 17 or later.
Some parts of your proposal (namely, switching to `string_view`) do not have a clear migration path, especially for C++03 users.
You didn't fully read my earlier email. There is no point using std::string_view with earlier than C++ 17. And boost::string_view doesn't have sufficient interop with std::string to substitute. The std::string_view message() is 100% C++ 17 or later only.
Other parts seem to be targeted at a rather niche use case but have high associated overhead that is going to be applied to all uses of `error_code`. And, on top of that, users' code may break, including silently. Sorry, but to me this doesn't look like a safe change that can be done to a widely used core library. Boost.System2, that will live side by side with the current Boost.System, seems more appropriate. I realize that you won't know how much of the world will be affected by the proposed changes.
Ultimately the decision lands with the maintainer of Boost.System, and it's what we're having this debate for. I'm not sure if that's still Beman entirely, I've noticed Peter sending some love in the direction of Boost.System recently. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/