https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119197
Bug ID: 119197 Summary: [feat req] `std::expected` should be nodiscard Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- See https://quuxplusone.github.io/blog/2024/12/08/should-expected-be-nodiscard/ and https://www.reddit.com/r/cpp/comments/1h9u4us/should_stdexpected_be_nodiscard/ (notice the top comment is by STL saying "no," and his next comment reverses his position to "strongly yes") — using Eint = std::expected<int, std::error_code>; Eint f_or_error() noexcept; It is invariably problematic to discard the result of a function that uses `expected` for error handling. That's the equivalent of enclosing an exception-throwing function call in `try { ... } catch(...){}`, discarding any error condition; but the language allows it to happen without any ceremony. It should of course still be possible to write the ceremony explicitly— (void)f_or_error(); The way we make this happen is by marking `std::expected` as [[nodiscard]]. Microsoft STL has already marked it, in https://github.com/microsoft/STL/pull/5174 martinmoene/expected-lite has already marked it. libc++ has fixed their tests to keep working when `std::expected` is marked nodiscard, although their own `std::expected` is not yet marked. Microsoft STL's commit *also* marked all the exception types, which (if libstdc++ did the same) would immediately fix #116866. --- In fact, if you're ever asked "When should I use variant<T,U> and when should I use expected<T,U>, given that they are physically equivalent?" — the answer is "expected<T,U> is designed for error-handling and is (should be) nodiscard; variant<T,U> is more general-purpose and is not nodiscard." The error-handlingness (i.e. the should-be-nodiscardness) of `expected` is pretty much its single defining characteristic. --- jwakely was initially concerned that compiler bug #85973 might have rendered such a marking completely moot, so it was a low priority in libstdc++; but my understanding is that this concern has been resolved: #85973 is triggered only in circumstances much more obscure than jwakely originally thought, and in fact marking std::expected as [[nodiscard]] would have an immediate beneficial effect in (1) ensuring error returns are handled correctly, and (2) aligning libstdc++'s diagnostics with MS STL's in this specific area.