I am facing an issue with C++20 in Visual Studio 2022 Community. The code works correctly in G++ but I get an internal compiler error with MSVC.
Here is the code:
#include <iostream>
struct Foo {
float* data;
Foo(float * const * const & address) :
data(*address)
{}
Foo(float ** const && address) :
data(*address)
{}
};
int main() {
int64_t size = 12;
float* data = new float[size];
float** address = &data;
auto foo = Foo(std::move(address));
}
Error:
Build started...
1>------ Build started: Project: ConsoleApplication4, Configuration: Debug x64 ------
1>Scanning sources for module dependencies...
1>main.cpp
1>main.cpp(26,35): fatal error C1001: Internal compiler error.
1>(compiler file 'msc1.cpp', line 1584)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
1>If possible please provide a repro here: https://developercommunity.visualstudio.com
1>Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>INTERNAL COMPILER ERROR in 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\HostX64\x64\CL.exe'
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>Done building project "ConsoleApplication4.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build started at 4:08 PM and took 01.716 seconds ==========
The error code is C1001, which suggests simplifying or changing the program. However, another project requires being able to differentiate between l-value and r-value pointers in a similar way. I would appreciate any assistance in resolving this issue.
Generally speaking, internal compiler errors aren't something that anyone outside the MSVC development team can really address, and the problem should be reported to that team.
However, as a "quick fix", we can note that
std::move(x)is equivalent to an appropriatestatic_cast<T&&>(x); from cppreference (bold emphasis mine):Thus, simply changing your
std::movecall to an equivalent cast makes MSVC happy:Looking at this in more detail, I notice that the MSVC implementation of
std::move<T>returns what astatic_castlike the above yields, using the type thatstd::remove_reference<T>::typeyields as the 'base type' for that cast. Here is the definition from the<type_traits>header:What seems to be confusing the compiler here is the lack of a
constqualifier on theaddressvariable. Adding that also makes MSVC happy: