Search

Wrong return type when running nested lambda by Bengt Gustafsson

Closed
as Fixed Help for as Fixed

1
0
Sign in
to vote
Type: Bug
ID: 634688
Opened: 1/5/2011 3:58:12 AM
Access Restriction: Public
0
Workaround(s)
0
User(s) can reproduce this bug
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
    };
}
Details (expand)

Visual Studio/Silverlight/Tooling version

Visual Studio 2010

What category (if any) best represents this feedback?

Compatibility

Steps to reproduce

compile code above

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

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

Expected results

no errors
File Attachments
0 attachments
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)
Sign in to post a workaround.