I find that nested lambda expressions are very slow to compile and generate huge .obj files. For example, on my computer, the following code generates a obj file of size 4766 KB:
int main()
{
auto f = []
{
auto f = []
{
auto f = []
{
auto f = []
{
auto f = []
{
};
};
};
};
};
}
And the following code (one more nesting level is added) will cause a C1128 error.
int main()
{
auto f = []
{
auto f = []
{
auto f = []
{
auto f = []
{
auto f = []
{
auto f = []
{
};
};
};
};
};
};
}
Also, they are very slow to compile. Is there any explanation for this? I'm using Visual C++ 2013.
This seems to be a bug in Visual C++, I've reported it to Microsoft: https://connect.microsoft.com/VisualStudio/feedback/details/813755/nested-lambdas-in-visual-c-2013-are-very-slow-to-compile-and-generate-huge-object-file.
Example. Because lambda expressions are typed, you can use them with C++ templates. The following example shows the negate_all and print_all functions. The negate_all function applies the unary operator- to each element in the vector object. The print_all function prints each element in the vector object to the console.
When we use lambda function inside another lambda function then it is called Nested Lambda Function. Here, when the object o with parameter 4 is called, the control shift to f () which is caller object of the whole lambda function. Then the following execution takes place-
As you pass the local variable x to the lambda, the compiler is unable to cache a created delegate. Let’s look at the decompiled code: There it is. A new instance of the c__DisplayClass1 () is created each time the Substring method is called. The parameter x we pass to the lambda is implemented as a public field of c__DisplayClass1.
The concepts of LINQ queries and lambda expressions are closely connected and have very similar implementation ‘under the hood.’ This means that all concerns we discussed for lambdas are also true for LINQs. If your LINQ query contains a closure, the compiler won’t cache the corresponding delegate.
Not sure how useful such deeply nested lambdas are but for what it is worth as far as I can tell this is a bug, the Visual Studio compiler limits document states (emphasis mine):
The C++ standard recommends limits for various language constructs. The following is a list of constructs where the Visual C++ compiler does not implement the recommended limits. The first number is the recommended limit and the second number is the limit implemented by Visual C++:
and includes the following bullet:
Nesting levels of compound statements, iteration control structures, and selection control structures [256] (256).
If we look at the grammar in the C++ draft standard compound-statement will eventually get back to primary-expression which includes lambda-expression. So Visual Studio should support up to 256
levels of nesting.
You could also see this by looking at the grammar for lambda-expression which is as follows:
lambda-introducer lambda-declaratoroptcompound-statement
The draft standard has a set of recommend limits in Annex B but they are only guidelines and do not determine compliance.
Update
The bug report the OP filed was updated recently to indicate this will be fixed in a future release.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With