Boost logo

Boost :

From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2020-07-22 14:38:25


On 21/07/2020 15:51, Alexander Grund via Boost wrote:
>
>> Finally, if anyone more expert at C++ than I can suggest how to fix
>> https://www.boost.org/development/tests/develop/developer/output/teeks99-dkr-dc10-2a-lc-boost-bin-v2-libs-outcome-test-comparison-test-clang-linux-10~c++2a~lc-debug-threading-multi-visibility-hidden.html,
>>
>> I'd appreciate the help.
>
> Just some observations that might help:
>
> - Failing test is BOOST_CHECK(a == b); with "outcome<int> a(1);   
> result<int> b(1);"
> - Hence the operation is "operator==(outcome, result)
> - Failing stacktrace shows bottom-most: "operator==(const
> basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b)" so the
> other way round
> - you define the availability and noexceptness basically as "b == a"
> reversing the results

All correct.

> Is it possible that outcome<T> and result<T> are convertible? If so,
> that would explain the recursion: to check a==b you need to check b==a
> so you need to check a==b, ...

An outcome<T> can be explicitly constructed from a result<T> yes.

But the recursion isn't from that. result == outcome is available if
outcome == result is available. outcome<A, B> == result<C, D> is
available if the expressions A == C and B == D are valid. As A and C are
both ints, and B and D are both error_code, this should "just work", and
indeed it does on GCC and MSVC, and indeed clang if in a C++ standard
before C++ 20.

For some reason I don't understand, clang in C++ 20 mode seems to loop
the result == outcome step i.e. in the constraints that result ==
outcome is available if and only if outcome == result is available, it
considers the availability of the result == outcome overload itself. As
you suggest, if an outcome were *implicitly* constructible from a
result, that might be a valid consideration. But it is not available due
to the explicit constructibility, so the compiler should never consider it.

Another option is that this is simply a corner case bug in clang.
Xcode's clang is actually pretty bug ridden, Outcome's unit tests fail
badly on Xcode clang, I had to go disable a whole bunch of them to
achieve a pass. But LLVM clang is pretty good, generally. It's the best
of all the major compilers for this sort of stuff, in my opinion.

Now, there is the argument that in C++, just because A == B is available
doesn't mean than B == A is available, and Outcome ought to reflect that
properly. This is one of those many areas where I've deliberately been
lazy, and not spent code and thus maintenance time on what are in my
opinion pathological corner case support. To date, no users have
complained :)

Niall


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