-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<variant>: std::variant
template param order determines if destructor is constant expression
#5329
Comments
This is probably a bug MSVC as the example is correctly accepted by Clang + MSVC STL (and Clang + libc++, Clang + libstdc++, GCC + libstc++). |
I was going to say the same (and I have actually reported this compiler bug in october 2023 but its still unfixed). But I just came up with a way to fix it? Splitting Then specializations for when So far all I tried was to get this to compile, which it does! (the only other change is inside what are your thoughts on a fix like this? template <bool _TrivialDestruction, class... _Types>
class _Variant_storage_ {};
struct _Placeholder_ty_variant_start {};
template <class... _Types>
using _Variant_storage = _Variant_storage_<conjunction_v<is_trivially_destructible<_Types>...>, _Placeholder_ty_variant_start, _Types...>;
template <class... _Types>
using _Variant_storage_recurse = _Variant_storage_<conjunction_v<is_trivially_destructible<_Types>...>, _Types...>;
template <class _First, class... _Rest>
class _Variant_storage_<true, _First, _Rest...> { // Storage for variant alternatives (trivially destructible case)
// ....
union {
remove_cv_t<_First> _Head;
_Variant_storage_recurse<_Rest...> _Tail;
};
// ....
};
template <class _First, class... _Rest>
class _Variant_storage_<false, _First, _Rest...> { // Storage for variant alternatives (non-trivially destructible case)
// ....
union {
remove_cv_t<_First> _Head;
_Variant_storage_recurse<_Rest...> _Tail;
};
// ....
};
template <class... _Rest>
class _Variant_storage_<true, _Placeholder_ty_variant_start, _Rest...> { // Outermost storage for variant alternatives (trivially destructible case)
// ....
union {
char _placeholder_Head;
_Variant_storage_recurse<_Rest...> _Variant_Internal;
};
// ....
};
template <class... _Rest>
class _Variant_storage_<false, _Placeholder_ty_variant_start, _Rest...> { // Outermost storage for variant alternatives (non-trivially destructible case)
// ....
union {
char _placeholder_Head;
_Variant_storage_recurse<_Rest...> _Variant_Internal;
};
// ....
}; |
What's the VS Developer Community bug number/link?
That's a library workaround, not a true fix. The best solution is to get a compiler fix. We do add library workarounds from time to time, but we can't mess with data structure representations in any significant way because that would break ABI (binary compatibility). |
Bug report link: https://developercommunity.microsoft.com/t/Constexpr-union-destructor-cannot-result/10486017
I too would prefer a compiler fix but I waited for a year and that didn't happen (which is fair there are more important bugs). Just thought I might try to think of a workaround in the meantime
Also yes abi, I was unsure if change to a union representation with an additional empty member would break abi since in practice the object representation should end up the same (I thought I had mentioned that but apparently I forgot) |
Thanks, I've marked our internal mirror of that bug as "STL-requested" and noted the |
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 aconstexpr
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
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:
The text was updated successfully, but these errors were encountered: