Boost logo

Boost :

Subject: Re: [boost] [system] Would it be possible to trial a breaking change to Boost.System and see what happens?
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2018-01-14 00:27:15


> 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/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk