`<variant>`: `visit` should not throw for nothrow movable types
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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