decltype of entity that may be captured: should it yield the type of the entity outside of the lambda?

117 Views Asked by At

Consider this simple self-contained code:

template<typename T>
void foo();

void bar() {
    int i;
    auto l = [&i]() -> decltype(auto) {
        decltype(auto) x = i;
        foo<decltype(x)>();
        foo<decltype(i)>();
        return static_cast<decltype(i)>(i);
    };
    l();
    foo<decltype(l())>();
}

GCC Generates the following:

bar():
        sub     rsp, 8
        call    void foo<int&>()
        call    void foo<int>()
        add     rsp, 8
        jmp     void foo<int>()

Clang Generates the following:

bar():                                # @bar()
        push    rax
        call    void foo<int>()
        call    void foo<int>()
        pop     rax
        jmp     void foo<int>()                     # TAILCALL

MSVC Generates the following:

void bar(void) PROC                                        ; bar, COMDAT
$LN8:
        sub     rsp, 40                             ; 00000028H
        call    void foo<int &>(void)                  ; foo<int &>
        call    void foo<int &>(void)                  ; foo<int &>
        add     rsp, 40                             ; 00000028H
        jmp     void foo<int &>(void)                        ; foo<int &>
void bar(void) ENDP   

 

It seems all three compiler disagree. Which one is right and what part of the C++ standard confirms it?

In my mind, decltype(i) should always be int, and never int&, no matter if it is captured or not.

Obligatory compiler explorer link

0

There are 0 best solutions below