ned14 / status-code

Proposed SG14 status_code for the C++ standard

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

example/quick_status_code_from_enum.cpp failed to compile for gcc version <= 7

lzhangzz opened this issue · comments

when trying to compile the quick status code from enum example, I got the following error for gcc version <= 7.

<source>: In function 'constexpr system_error2::quick_status_code_from_enum_code<another_namespace::AnotherCode> another_namespace::status_code(another_namespace::AnotherCode)':
<source>:76:144: error: could not convert 'c' from 'another_namespace::AnotherCode' to 'system_error2::quick_status_code_from_enum_code<another_namespace::AnotherCode> {aka system_error2::status_code<system_error2::_quick_status_code_from_enum_domain<another_namespace::AnotherCode> >}'
 constexpr inline SYSTEM_ERROR2_NAMESPACE::quick_status_code_from_enum_code<another_namespace::AnotherCode> status_code(AnotherCode c) { return c; }
                                                                                                                                                ^
<source>: In function 'int main(int, char**)':
<source>:84:88:   in constexpr expansion of 'another_namespace::status_code(another_namespace::AnotherCode)()'
<source>:84:88: error: constexpr call flows off the end of the function
   SYSTEM_ERROR2_CONSTEXPR14 auto v = status_code(another_namespace::AnotherCode::error2);
                                                                                        ^

looks like implicit conversion from enum is not working.

Oh dear, and here I was sending you to this from ned14/outcome#254.

I can repeat your issue exactly: https://godbolt.org/z/xo9dE6EqY

As much as this is me hand waving away the problem, if you're stuck on GCC 7, I'd suggest just explicit constructing wherever GCC 7 refuses to find the implicit conversion. So, for example: https://godbolt.org/z/vfz9WTMcG

As I mentioned in the other issue, GCC 7 is still my primary dev compiler for LLFIO, and I haven't found any showstopper problems. It also does heavy complex customisation of status code, so it's not a trivial user.

I agree that constructing explicitly is sufficient as a workaround.

However, I'm curious why this is happing. And to my suprise I just find that even on GCC7 static_assert(std::is_convertible<AnotherCode, StatusCode>::value) does not complain at all. As I recall that is_convertible is defined as the well-form-ness of To f() { return std::declval<From>(); }.

Recent releases of compilers haven't had the QoI that older ones did. GCC 6 was quite solid compared to the many more surprises in say GCC 10, which I still can't use in production because it just doesn't work well enough. clangs up until and including 7 were also solid, since I see weird failures to emit symbols in heavy metaprogrammed code. The only compiler uncategorically better than before is MSVC.

is_convertible will be a compiler intrinsic in newer compilers, and as such can experience bugs. Recursive instantiation of constexpr possible code is a common source of trait intrinsic bugs.

Fixed!