microsoft / microsoft/STL

`<variant>`: `visit` should not throw for nothrow movable types

Open
#254 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

performance vNext
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

Describe the bug
For "simple" variants like std::variant<int,float,double> there can never be a "valueless_by_exception" state. Hence for these cases std::visit should be noexcept(true) and no exception code should be generated which allows for more optimizations later on.

Command-line test case

#include <variant>

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

struct T0 {};
struct T1 {};
struct T2 {};
struct T3 {};
struct T4 {};
struct T5 {};
struct T6 {};
struct T7 {};
struct T8 {};
struct T9 {};

using example_variant = std::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>;

int do_visit(example_variant v)
{
    return std::visit(overloaded {
        [](T0 val) { return 3; },
        [](T1 val) { return 5; },
        [](T2 val) { return 8; },
        [](T3 val) { return 13; },
        [](T4 val) { return 17; },
        [](T5 val) { return 29; },
        [](T6 val) { return 53; },
        [](T7 val) { return 85; },
        [](T8 val) { return 65; },
        [](T9 val) { return 233; },
    }, v);
}

Expected behavior
You can see the generated code at https://godbolt.org/z/D2Q5ED in comparison with Clang and GCC which both have the noexcept/omission of the potential throw.

Note how the optimal code looks like for Boost.Variant2 which is like return values[v.index()]: https://godbolt.org/z/EawzdG

Summary
Track the possibility of the valueless state, make it constexpr accessible and use it to avoid generating code that can in practice never be reached. This will improve performance and reduce generated code size.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the std::variant and std::visit implementation entry points and reproduce the supplied example_variant command-line case. Compare generated code with the linked Godbolt examples; done means the nothrow movable case is recognized, std::visit is noexcept where appropriate, and unreachable exception handling is omitted.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.