<variant>: `std::variant` template param order determines if destructor is constant expression
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.2k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
Describe the bug
The order of the template parameters in variant influences if the destructor is a constant expression.
I think it might be related to a compiler behaviour/bug with constexpr destructors being weird with unions.
It seems that it requires the very first element to have a constexpr destructor in order for the whole object to have a constexpr destructor.
From playing around it also seems like you're using the only case where this even works at all on msvc: recursive templates where the outer-most case is the first union field and has a constexpr destructor.
Command-line test case
https://godbolt.org/z/h5b766seM
#include <variant>
struct Trivial {};
struct NonTrivial {
NonTrivial() {}
~NonTrivial() {}
};
// Trivial first
constexpr std::variant<Trivial, NonTrivial> v0{Trivial{}};// no error
// Nontrivial first
constexpr std::variant<NonTrivial, Trivial> v1{Trivial{}};// error
Expected behavior
I would expect it to either error on both, or error on neither
STL version
It becomes an issue since VS16.11 up until the latest on godbolt (idk specifically which stl version that is sorry)
Before that both are errors so its not a problem I guess
Additional context
There are 4 potential solutions I could think of:
- Say the current behaviour is intended (strange but potentially only good option)
- Make this invalid in both cases (don't do this please)
- Somehow fix the msvc compiler to make the destructor constexpr-ness not be so weird
- Detect if there is a constexpr destructable member in some outer template, and reorder the template for storage so that the constexpr one is always first. But I don't know if this would be possible and still remain standard compliant and not break abi (I suspect it would break both)
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 with the linked Compiler Explorer test case and the std::variant destructor behavior for the two template-parameter orders. Investigate whether the difference is caused by the MSVC compiler or STL implementation; done means documenting the intended behavior and agreeing on a resolution or fix.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100