Remix.run Logo
on_the_train 5 hours ago

std::optional is unsafe in idiomatic use cases? I'd like to challenge that.

Seems like the daily anti c++ post

steveklabnik 5 hours ago | parent | next [-]

Two of the authors are libc++ maintainers and members of the committee, it would be pretty odd if they were anti C++.

maccard 4 hours ago | parent | prev | next [-]

I’m very much pro c++, but anti c++’s direction.

> optional is unsafe in idiomatic use cases? I’d like to challenge that.

    std::optional<int> x(std::nullopt);
    int val = *x;

Optional is by default unsafe - the above code is UB.
on_the_train 4 hours ago | parent | next [-]

But using the deref op is deliberately unsafe, and never used without a check in practice. This would neither pass a review, nor static analysis.

canyp 4 hours ago | parent | next [-]

GP picked the less useful of the two examples. The other one is a use-after-move, which static analysis won't catch beyond trivial cases where the relevant code is inside function scope.

I also agree with them: I am pro-C++ too, but the current standard is a fucking mess. Go and look at modules if you haven't, for example (don't).

mohinder 4 hours ago | parent | prev | next [-]

> This would neither pass a review, nor static analysis

I beg to differ. Humans are fallible. Static analysis of C++ cannot catch all cases and humans will often accept a change that passes the analyses.

einpoklum 3 hours ago | parent [-]

> Static analysis of C++ cannot catch all cases

You're ignoring how static analysis can be made to err on the side of safety rather than promiscuity.

Specifically, for optional dereferencing, static analysis can be made to disallow it unless it can prove the optional has a value.

IshKebab 3 hours ago | parent | prev [-]

> never used without a check in practice

Ho ho ho good one.

TinkersW 4 hours ago | parent | prev [-]

That is actually memory safe, as null will always trigger access violation..

Anyway safety checked modes are sufficient for many programs, this article claims otherwise but then contradicts itself by showing that they caught most issues using .. safety checked modes.

steveklabnik 4 hours ago | parent | next [-]

It is undefined behavior. You cannot make a claim about what it will always do.

maccard 4 hours ago | parent | prev | next [-]

>null will always trigger access violation..

No, it won't. https://gcc.godbolt.org/z/Mz8sqKvad

TinkersW 4 hours ago | parent [-]

Oh my bad, I read that as nullptr, I use a custom optional that does not support such a silly mode as "disengaged"

canyp 4 hours ago | parent | next [-]

How is that an optional then?

The problem is not nullopt, but that the client code can simply dereference the optional instead of being forced to pattern-match. And the next problem, like the other guy mentioned above, is that you cannot make any claims about what will happen when you do so because the standard just says "UB". Other languages like Haskell also have things like fromJust, but at least the behaviour is well-defined when the value is Nothing.

maccard 2 hours ago | parent | prev [-]

What do you return if there is no value set? That’s the entire point of optional.

wild_pointer 4 hours ago | parent | prev [-]

You didn't read this, did you? https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/

It's not a pointer.

boulos 4 hours ago | parent | prev | next [-]

They linked directly to https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/ which did exactly what I'd guessed as its example:

> The following code for example, simply returns an uninitialized value:

  #include <optional>

  int f() {
    std::optional<int> x(std::nullopt);
    return *x;
  }
on_the_train 4 hours ago | parent [-]

But that is not idiomatic at all. Idiomatic would be too use .value()

Maxatar 3 hours ago | parent | next [-]

Just a cursory search on Github should put this idea to rest. You can do a code search for std::optional and .value() and see that only about 20% of uses of std::optional make use of .value(). The overwhelming majority of uses off std::optional use * to access the value.

electroly 3 hours ago | parent | prev | next [-]

Sadly I have lots of code that exclusively uses the dereference operator because there are older versions of macOS that shipped without support for .value(); the dereference operator was the only way to do it! To this day, if you target macOS 10.13, clang will error on use of .value(). Lots of this code is still out there because they either continue to support older macOS, or because the code hasn't been touched since.

IshKebab 3 hours ago | parent | prev [-]

Not only is this a silly No True Scotsman argument, but it's also absolute nonsense. It's perfectly idiomatic to use `*some_optional`.

canyp 4 hours ago | parent | prev [-]

It is discussed in the linked post: https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/

tl;dr: use-after-move, or dereferencing null.