Boost logo

Boost :

From: Alexander Grund (alexander.grund_at_[hidden])
Date: 2020-07-22 14:47:10


Am 22.07.20 um 16:38 schrieb Niall Douglas via Boost:
> On 21/07/2020 15:51, Alexander Grund via Boost wrote:
>> 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 :)

What about the fact that Clang considers "operator==(const basic_result,
const basic_outcome)" for a test "operator==(outcome, result)"? Have you
checked that? This way you might find where it converts one into
another. Maybe even check that in isolation by assigning  "b = a" first
and see what it does.
Could you check that locally in a file having only this? Maybe remove
the constraints for this test to make it compile and debug it through to
see why it tries that?

For why "clang in C++20": You switch your macros to use concepts instead
of template sfinae in C++20, don't you? If so, temporarily disable that?
Maybe this switch enables a ctor that is otherwise explicit or disabled?




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