Skip to content

<variant>: std::variant template param order determines if destructor is constant expression #5329

Open
@Veeloxfire

Description

@Veeloxfire

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:

  1. Say the current behaviour is intended (strange but potentially only good option)
  2. Make this invalid in both cases (don't do this please)
  3. Somehow fix the msvc compiler to make the destructor constexpr-ness not be so weird
  4. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcompilerCompiler work involved

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions