Using the following declarations:
#include <array>
template <typename V> void makeError(V& v) {}
the following code snippet fails to compile under MSVC 16.11.13 with /std:c 17
:
int main() {
[&]() {
std::array bugs{0};
[&]() { makeError(bugs); };
};
return 0;
}
The error message is as follows: main.cpp(9,5): error C2955: 'std::array': use of class template requires template argument list
The same code compiles perfectly fine under GCC 10.4 with --std=c 17
. The real problem came up when I tried removing the inner closure:
int main() {
[&]() {
std::array bugs{0};
makeError(bugs);
};
return 0;
}
Or the outer closure:
int main() {
std::array bugs{0};
[&]() { makeError(bugs); };
return 0;
}
Both of these compile happily under MSVC and GCC.
Is the first snippet invalid C ? If so, what part of the standard am I violating?
CodePudding user response:
Looks like this is a bug in msvc's legacy lambda processor. Your code compiles if you pass /Zc:lambda
: https://godbolt.org/z/91z4chhTx
This seems to be the matching bug report: https://developercommunity.visualstudio.com/t/class-template-argument-deduction-fails-in-the-bod-1/414204
How I found this
I would always recommend using godbolt in cases like this, since it allows you to quickly switch between compilers, versions and command line args.
If something smells like a compiler bug, checking the latest versions is always a good idea. If something compiles under gcc & clang, but not msvc, it smells like a compiler bug.
I tried your code in the latest msvc and since it involves lambdas and captures, I remembered that there were changes to that in c 20, so I tried compiling as such. Since that worked, I had look through cppreference to see if I could find any relevant change to the standard that might legitimately cause this. I didn't find any, but then remembered that msvc has also constantly be increasing its standards conformance over the recent years.
So I used /permissive-
with c 17 and once I noticed that this builds, I had a look through the conformance flags and found /Zc:lambda
.
This confirmed this as a fixed compiler bug to me. And fixed bugs often have bug reports, so I googled the keywords that seemed relevant to the situation: msvc nested lambdas template deduction. The bug report is the second result for me.