How can the reader of *get_if() tell if the author intended this optimization, or was just lazy?


Function names should communicate intent. "get_if()" communicates that you don't know if the variant holds the the type you are asking for or not. *get_if() communicates that you forgot to check.


My preference would be static_variant_cast<>, following static_cast<> and static_pointer_cast<>. The latter two communicate that the author knows there is a safety violation if some other check is not performed, and confirms they are aware of it, enough to have typed such a long and ugly name.


On 26/10/2020 03.25, Tony V E via Std-Proposals wrote:
I don't think you need unreachable. 
*get_if should be enough. Unconditionally dereference the result.

Sent from my BlackBerry portable Babbage Device
From: Justin Bassett via Std-Proposals
Sent: Sunday, October 25, 2020 9:16 PM
To: Std-Proposals
Cc: Justin Bassett
Subject: Re: [std-proposals] std::as

I'm glad to see that clang can also optimize this get_if access; it used to be unable to do so. MSVC is also unable to optimize this when using __assume ( https://docs.microsoft.com/en-us/cpp/intrinsics/assume?view=vs-2019 ) (which is the same as Clang's __builtin_assume() https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume ) instead of __builtin_unreachable().

In theory, a portable __builtin_unreachable() would be:

[[noreturn]]
inline void unreachable() {} // basically, unconditionally trigger undefined behavior

In practice, only GCC seems to recognize this.

--Justin Bassett

On Sun, Oct 25, 2020 at 5:59 PM Ryan P. Nicholl via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
[build] C:\Users\Ryan\rpnx-core\private\sources\all\test3.cpp(119,5): error C3861: '__builtin_unreachable': identifier not found [C:\Users\Ryan\rpnx-core\build\rpnx-core-test3.vcxproj]

Great idea, except that __builtin_unreachable() is a GCC specific extension, and is not part of standard C++. (It would be nice to be able to do this in a cross platform way though! But that is for another discussion.)

--
Ryan P. Nicholl
Tel: (678)-358-7765
Personal Email: rnicholl@protonmail.com
Tox: 52B3A61CDAF88BCC854F568933F071E3530600CDBA3D5354AADC9AD179575D68021AE959719D


‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Sunday, October 25, 2020 8:50 PM, Barry Revzin <barry.revzin@gmail.com> wrote:



On Sun, Oct 25, 2020 at 7:41 PM Ryan P. Nicholl via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
I decided to implement a new class based on std::variant. I call it "rpnx::derivator", but it's basically "allocating_variant". I tried to make it as similar to std::variant as possible. When looking at this, I noticed something weird about std::variant. There is no "zero overhead" way to get the element contained by the variant, as std::get<I> checks for invalid access and throws an exception if invalid. To solve this issue, I would like to propose std::as, which works the same as std::get, but accessing the wrong type is undefined behavior instead of throwing an exception.

--
Ryan P. Nicholl
Tel: (678)-358-7765
Personal Email: rnicholl@protonmail.com
Tox: 52B3A61CDAF88BCC854F568933F071E3530600CDBA3D5354AADC9AD179575D68021AE959719D

You can achieve this by using std::get_if() and marking the nullptr case as unreachable. For example:

auto f(std::variant<intdouble>& v) -> int* {
    return std::get_if<int>(&v);
}

auto g(std::variant<intdouble>& v) -> int* {
    auto p = std::get_if<int>(&v);
    if (not p) __builtin_unreachable();
    return p;
}

On -O1, f emits a check but g does not: https://godbolt.org/z/9G9fd5.

Barry

--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals