You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cl compiles the above just fine under /std:c++20 and /std:c++latest, and I believe this should work fine under C++20 and above. Recent versions of gcc and clang both also work fine with their default standard library: https://godbolt.org/z/YhfW8M9b6.
But clang-cl (with MS STL) rejects this code, saying that z11 and z12 cannot be initialized by constant expressions:
C:\test>clang-cl /EHsc /std:c++20 .\repro.cpp
.\repro.cpp(19,16): error: constexpr variable 'z11' must be initialized by a constant expression
19 | constexpr auto z11 = Z1{0}.z.index();
| ^ ~~~~~~~~~~~~~~~
.\repro.cpp(19,22): note: subexpression not valid in a constant expression
19 | constexpr auto z11 = Z1{0}.z.index();
| ^
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Variant_storage_()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Variant_base()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Variant_destroy_layer_()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Non_trivial_copy()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Non_trivial_move()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Non_trivial_copy_assign()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~_Non_trivial_move_assign()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.z.~variant()'
.\repro.cpp(19,22): note: in call to 'Z1{0}.~Z1()'
.\repro.cpp(20,16): error: constexpr variable 'z12' must be initialized by a constant expression
20 | constexpr auto z12 = Z1{Y{}}.z.index();
| ^ ~~~~~~~~~~~~~~~~~
.\repro.cpp(20,22): note: subexpression not valid in a constant expression
20 | constexpr auto z12 = Z1{Y{}}.z.index();
| ^
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Variant_storage_()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Variant_base()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Variant_destroy_layer_()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Non_trivial_copy()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Non_trivial_move()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Non_trivial_copy_assign()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~_Non_trivial_move_assign()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.z.~variant()'
.\repro.cpp(20,22): note: in call to 'Z1{Y{}}.~Z1()'
2 errors generated.
STL version
Microsoft Visual Studio Community 2022
Version 17.11.0
But I believe the issue persists in the most recent version too.
Additional context
In my real code, X is std::vector. std::variant works just fine if std::vector is directly in the list of alternatives, but it fails if one of the alternatives contains std::vector as a subobject.
If I comment out z11 and z12, then now it compiles fine. Or if I explicitly default the destructor of Y, then it now accepts the code.
Another funny thing is that this issue appears only if std::variant contains both a trivially destructible type and a non-trivially destructible type. Like, if I replace int by X then now it works fine.
I believe this is a clang bug not MS STL's fault, but will it make sense if MS STL can provide a workaround? Even if you don't want to fix this from your side, I thought it would be helpful for you to be aware of the issue.
Note: I did not make a bug report to LLVM because I'm not sure what exactly is causing this. As I said clang works with both libstdc++ and libc++ just fine (only with the most recent version though; it seems older versions still use placement new so it doesn't work but for a totally different reason), but I couldn't spot what exactly is different between libc++/libstdc++ and MS STL.
The text was updated successfully, but these errors were encountered:
jk-jeon
added a commit
to jk-jeon/idiv
that referenced
this issue
Aug 21, 2024
Please see the following:
cl
compiles the above just fine under/std:c++20
and/std:c++latest
, and I believe this should work fine under C++20 and above. Recent versions ofgcc
andclang
both also work fine with their default standard library: https://godbolt.org/z/YhfW8M9b6.But
clang-cl
(with MS STL) rejects this code, saying thatz11
andz12
cannot be initialized by constant expressions:STL version
Microsoft Visual Studio Community 2022
Version 17.11.0
But I believe the issue persists in the most recent version too.
Additional context
In my real code,
X
isstd::vector
.std::variant
works just fine ifstd::vector
is directly in the list of alternatives, but it fails if one of the alternatives containsstd::vector
as a subobject.If I comment out
z11
andz12
, then now it compiles fine. Or if I explicitly default the destructor ofY
, then it now accepts the code.Another funny thing is that this issue appears only if
std::variant
contains both a trivially destructible type and a non-trivially destructible type. Like, if I replaceint
byX
then now it works fine.I believe this is a clang bug not MS STL's fault, but will it make sense if MS STL can provide a workaround? Even if you don't want to fix this from your side, I thought it would be helpful for you to be aware of the issue.
Not sure if this is related to one of the issues you are tracking: llvm/llvm-project#59854.
Note: I did not make a bug report to LLVM because I'm not sure what exactly is causing this. As I said clang works with both
libstdc++
andlibc++
just fine (only with the most recent version though; it seems older versions still use placementnew
so it doesn't work but for a totally different reason), but I couldn't spot what exactly is different betweenlibc++
/libstdc++
and MS STL.The text was updated successfully, but these errors were encountered: