4

I have a program that I would like to build in Visual Studio 2026, but struggle with the errors appearing.

One simplified piece of code is as follows:

void f(const void*) {}

int main() {
    constexpr float one[1] = { 1.0f };
    [&]() {
        f(one);
        f(&one[0]);
    }();
}
  • In /std:c++17 mode, MSVC accepts the program just fine.
  • In /std:c++20 mode, MSVC shows two errors:
<source>(6): error C2326: 'auto main::<lambda_1>::operator ()(void) const': function cannot access 'one'
<source>(7): error C2101: '&' on constant
  • and in /std:c++latest mode, it shows only error C2101.

Online demo

What changed in C++20 and later versions that caused the program to be rejected?

2
  • 2
    In MSVC, /std:c++17 alone does not compile the code by the C++17 standard, it has an implicit /permissive which allows for Microsoft extensions. If you add /permissive- to the compile flags, the code won't compile. MSVC /std:c++20 changed /permissive- (Microsoft extensions (mostly) disable) to be the default. Commented Feb 22 at 18:35
  • godbolt.org/z/bYTYKjbTY Commented Feb 23 at 13:56

2 Answers 2

4

What changed in C++20 and later versions that caused the program to be rejected?

Flag /permissive- is enabled by default from C++20 in msvc. Microsoft has many extensions that results in successful compilation of an invalid C++ program. If you use /permissive- flag with C++17, you'll notice that msvc also starts rejecting the said program(which is incorrect behavior as the program is well-formed). This means that msvc was already rejecting the program(as far as standard compliance is concerned)


There is a closely related msvc bug that was fixed just 4 days ago(on 19-feb-2026). The reported bug says:

A fix for this issue is now available in preview release. Try out the fix by installing the most recent preview from  https://visualstudio.microsoft.com/vs/preview/.

Sign up to request clarification or add additional context in comments.

Comments

0

In C++20, even if a variable is constexpr, if you take its address or pass an array (which decays to a pointer), it is "ODR-used." This requires the variable to be captured.

void f(const void*) {}

int main() {
    constexpr float one[1] = { 1.0f };
    
    // Capture the pointer to the array explicitly
    [ptr = one]() {
        f(ptr);
        f(&ptr[0]);
    }();
}

But OP already does capture the variable by refence. And other compilers compile his code just fine godbolt.org/z/5G98nWP9f
I think we was very specific about the compiler. What your exmaple fhave in common with msvc

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.