Wrong return type when running nested lambda - by Bengt Gustafsson

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


1
0
Sign in
to vote
ID 634688 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 1/5/2011 3:58:12 AM
Access Restriction Public

Description

This code renders an error message on the assignment in the nested lambda, but not on the outer one. The message claims that running the lambda returns int!

This is (probably) a further simplified example of the bug I reported earlier today, which involved operator overloading. What I didn't realize then was that due to the present bug my overloaded operators were never called!

class Class {
};


void Testit()
{
	Class& obj = [&]()->Class& { return *new Class; }(); // no compiler error
	[&]()->double {
		Class& obj = [&]()->Class& { return *new Class; }(); // compiler error
	};
}
Sign in to post a comment.
Posted by Microsoft on 2/4/2011 at 1:09 PM
Hi:
    Thanks for reporting the issue.
    A fix has been checked into the compiler sources. The fix should show up in the next release of Visual C++.

Xiang Fan
Visual C++ Compiler Team
Posted by Bengt Gustafsson on 1/7/2011 at 2:42 AM
The problem seems specific to the case when the inner lambda returns a reference. If make the return type a pointer instead it compiles. But then another strange thing happens. If I place a unary * in front of the [&] introducer I get other compile errors. Enclosing the lambda definition and call in a parenthesis does not help. Finally I had to resort to a hack:

class Class {
};

class Helper {
} hlp;

Class& operator+(Class* lhs, Helper& rhs) { return *lhs; }

void Testit()
{
    Class& obj = *[&]()->Class* { return new Class; }();
    [&]()->double {
        Class& obj = [&]()->Class* { return new Class; }()+hlp;
        return 3.14;
    };
}

Here the +hlp calls a binary operator which is actually a pointer deref in disguise. This works!

The below code does not:

class Class {
};

void Testit()
{
    Class& obj = [&]()->Class& { return *new Class; }();
    [&]()->double {
        Class& obj = *([&]()->Class* { return new Class; }());
        return 3.14;
    };
}

It gives the following diagnostic:

c:\privat\src\bgui\bug2.cpp(13): error C2100: illegal indirection
c:\privat\src\bgui\bug2.cpp(13): error C2440: 'initializing' : cannot convert from 'int' to 'Class &'

It is hard for me to say if this is a separate bug but it seems related as this diagnostic too talks about 'int'. The code also works on the outer lambda level, even without the extra () level. But this means that even if the return type is Class* there's something fishy!

Note by the way that this error report, in contrast with other bugs you have deemed as low prioerity, does not concern itself with the automatic deduction of the lambda return type. Even with an explicitly stated return type it fails. Relying on the operator+ workaround is hopelessly obscure...
Posted by Microsoft on 1/5/2011 at 6:01 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 1/5/2011 at 4:13 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)