Closed danielvandenberg95 closed 5 months ago
Got it reproduced:
CL.exe /c /Zi /JMC /nologo /W4 /WX- /diagnostics:column /sdl /MP24 /Od /Ob0 /D _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS /D _SILENCE_CXX23_ALIGNED_STORAGE_DEPRECATION_WARNING /D _HEAPDEBUG=0 /D DEBUG=1 /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /Gy- /fp:precise /fp:except- /Zc:wchar_t /Zc:forScope /Zc:inline /std:c++latest /permissive /external:W4 /Gd /TP /wd4458 /FC /errorReport:prompt /MP /Zc:__cplusplus repro.cpp
#include <yvals_core.h>
#include <xloctime>
#include <expected>
#include <string>
struct test {
int x;
int y;
};
using err = std::string;
std::expected<std::pair<int, int>, err> testFunction() {
return std::pair<int, int>{ 5, 5 };
}
The problem disappears when removing /permissive
Confirmed that /permissive /MD
and /permissive /MDd
can cause the problem. /permissive-
(by default in C++20 and later modes), /MT
, and /MTd
are fine. Godbolt link.
Furtherly reduced example:
#include <xloctime>
//
#include <expected>
#include <string>
std::expected<std::pair<int, int>, std::string> testFunction() {
return std::pair<int, int>{ 5, 5 };
}
At the first glance, I guess this is a compiler bug. But also note that <xloctime>
is an internal header which shouldn't be directly included by user code.
~Can you reproduce the problem with only standard headers (directly) included?~
Edit: This example only includes necessary standard headers and reproduces the problem (Godbolt link).
#include <expected> // for std::expected
#include <locale> // explicit instantiation definition(s) in <locale> can be problematic
#include <string> // for std::string
#include <utility> // for std::pair
std::expected<std::pair<int, int>, std::string> testFunction() {
return std::pair<int, int>{5, 5};
}
Of course they can. Just replace <xloctime>
with <locale>
.
Roughly reduced to the following (Godbolt link):
#include <concepts> // for std::ranges::swap and std::same_as
#include <expected> // for std::expected
#include <string> // for std::string and std::char_traits
#include <utility> // for std::declval
template <class ElemT, class Traits>
struct my_outputter {};
template <class ElemT, class Outputter = ::my_outputter<ElemT, std::char_traits<ElemT>>>
struct my_putter {
void do_put_like() const {
// /permissive causes the ADL-found std::swap to be selected for my_outputter<char, std::char_traits<char>>
static_assert(std::same_as<
decltype(std::ranges::swap(std::declval<Outputter&>(), std::declval<Outputter&>())), void>);
}
};
// explicit instantiation can be problematic
template struct my_putter<char, ::my_outputter<char, std::char_traits<char>>>;
std::expected<int, std::string> testFunction() {
return 42;
}
/MD
and /MDd
merely trigger the explicit instantiation via conditional compilation, so only the /permissive
option is actually problematic IIUC.
In MSVC STL, std::copy
needs to detect whether the iterator is contiguous, via std::contiguous_iterator
since C++20. and std::contiguous_iterator
eventually relies on std::swappable
which uses std::ranges::swap
. ~It seems that ADL in std::ranges::swap
behaves differently in /permissive
and /permissive-
modes.~ #4363 may be related.
This is probably a bug of MSVC (or the nature of permissive modes). Workaround seems possible (Godbolt link).
Edit: Reported DevCom-10652420. The major reason of the bug doesn't seem to be the behavioral difference of ADL.
Describe the bug
In one of my projects, std::expected throws errors error C7608: atomic constraint should be a constant expression and error C2131: expression did not evaluate to a constant I think the latter is caused by the former.
In order to reproduce the issue, I inlined headers, removing them untill the issue disappeared. and discarding as much code as possible. I ended up with the following code in one file in my project:
The full output I get while compiling this is:
When enabling a precompiled header, this error goes away. I can not enable a precompiled header for this project though.
Command-line test case
I have not been able to reproduce it in command line. My attempt has been with: cl /permissive /MP /GS /TP /W4 /wd"4458" /Gy- /Zc:wchar_t /Zi /Gm- /Od /Ob0 /sdl /Zc:inline /fp:precise /D "_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS" /D "_MBCS" /D "_SILENCE_CXX23_ALIGNED_STORAGE_DEPRECATION_WARNING" /D "_HEAPDEBUG=0" /D "DEBUG=1" /fp:except- /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++latest /FC /EHsc /nologo /diagnostics:column /JMC .\repro.cpp as these are the closest to the command line options that my actual project is using.
Expected behavior
I would expect this to compile without issue.
STL version
Microsoft Visual Studio Professional 2022 Version 17.9.6
Additional context
I'm still trying to narrow down the issue, but seem to be stuck.