Hello!
I have yet another C++ question I want to know answer to. That is:
- This code doesn't compile with error message
use of deleted function ‘main()::<lambda(auto:1)>::~<lambda>()’
int main() { // CE
int n = 1;
int a[n];
auto f = [&](auto f) -> void {
a[0] = 0;
};
}
- On the other side, replacing C-array with vector or specifying array length as compile-time constant or allocating it with
new
— every other way makes everything to work:
int main() { // OK
int n = 1;
vector<int> x(n);
int y[1];
int *z = new int[n];
auto f = [&](auto f) -> void {
x[0] = y[0] = z[0] = 0;
};
}
- The error also goes off if the lambda
f
doesn't accept any arguments declared asauto
. It also disappears if I capture the array by link directly:auto f = [&, &a]
.
So, why is it the case? I managed to find out that variable sized array are GCC extension but it doesn't clarify the doubt. The problem is not in the array allocation / initialization, but in lambda's destructor, which clearly needn't to destruct the array.
As far as I know, the array is just a pointer to its beginning and capturing it by copy, or by reference makes small difference — you either create new variable that points to the beginning of the array too, or you create a reference to the "main" pointer. Doesn't seem to be a problem.
So, this is quite a peculiar problem; it arose when I tried to combine recursive lambdas and C-arrays. Probably some C++ master would share some thoughts and improve my understanding and intuition of the language.
Intuition is easy: type of lambda
f
is smth like:And question there is "What type of
a
"? And that must be known type with known compilation time size (C++ required each object to be known size at the moment of creation).Answer is "since variable length array is not C++ standartized so it is whatever GCC decides to be".
Example 1:
Sucessfully compiles in GCC 7.3 C++17 (which is confusing since in labmdas without VLA
auto
param would be correct starts from C++14)Example 2:
Compiles and write 4 in GCC 7.3 C++17
Example #3:
Compiles and write 16 in GCC 10.2 C++20
Bottom line: don't use feature if you don't understand how it works. And don't use VLA in particular outside trivial cases (because it is designed for trivial cases like "Allocate local array without any move/copy of it").