C++ Logo

std-proposals

Advanced search

Re: [std-proposals] long return lambda

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Tue, 11 Apr 2023 15:36:29 +0200
A) Why not simply   auto BAIL = [p](void)->bool { strcpy(p, "0000000000000000"); return false; };   if ( SUCCESS != fpgaReadInt32(0x00f6, &p32[0]) ) return BAIL(); B) or create a scope guard (which automatically does the strcpy), and which can be deactivated in the success path.   C) or put the handling of success/bail into the surrounding function:   // lambda or 'real' function auto readtest = [p](void)->void {   if ( (SUCCESS != fpgaReadInt32(0x00f2, &p32[0])) || (0 == (p32[0] & 1)) ) return false; if ( SUCCESS != fpgaReadInt32(0x00f6, &p32[0]) ) return false; if ( SUCCESS != fpgaReadInt32(0x00fa, &p32[1]) ) return false;    }   if (!readtest())     strcpy(...);     return false; }   sprinf(...)   return true;   -----Ursprüngliche Nachricht----- Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Di 11.04.2023 15:17 Betreff:[std-proposals] long return lambda An:std-proposals <std-proposals_at_[hidden]>; CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>; Today I wrote the following function for a microcontroller:    bool Serial(char *const p)    {    #   define BAIL { strcpy(p, "0000000000000000"); return false; }        int32_t p32[2u];        if ( (SUCCESS != fpgaReadInt32(0x00f2, &p32[0])) || (0 == (p32[0] & 1)) ) BAIL        if ( SUCCESS != fpgaReadInt32(0x00f6, &p32[0]) ) BAIL        if ( SUCCESS != fpgaReadInt32(0x00fa, &p32[1]) ) BAIL        sprintf(p +  0u, "%08lx", static_cast<long unsigned>(p32[0]));        sprintf(p + 16u, "%08lx", static_cast<long unsigned>(p32[1]));        return true;    #   undef BAIL    } I would have liked to use a lambda instead of a macro there, but then I would have to write:    bool Serial(char *const p)    {        auto BAIL = [p](void)->void { strcpy(p, "0000000000000000"); };        int32_t p32[2u];        if ( (SUCCESS != fpgaReadInt32(0x00f2, &p32[0])) || (0 == (p32[0] & 1)) ) { BAIL(); return false; }        if ( SUCCESS != fpgaReadInt32(0x00f6, &p32[0]) ) { BAIL(); return false; }        if ( SUCCESS != fpgaReadInt32(0x00fa, &p32[1]) ) { BAIL(); return false; }        sprintf(p +  0u, "%08lx", static_cast<long unsigned>(p32[0]));        sprintf(p + 16u, "%08lx", static_cast<long unsigned>(p32[1]));        return true;    } So I thinking, what if we had a 'long return lamda'? The return statement from a 'long return lambda' is treated as a return statement from the enclosing function. As follows:    bool Serial(char *const p)    {        auto BAIL = [p](void) -> long return bool { strcpy(p, "0000000000000000"); return false; };        int32_t p32[2u];        if ( (SUCCESS != fpgaReadInt32(0x00f2, &p32[0])) || (0 == (p32[0] & 1)) ) BAIL();        if ( SUCCESS != fpgaReadInt32(0x00f6, &p32[0]) ) BAIL();        if ( SUCCESS != fpgaReadInt32(0x00fa, &p32[1]) ) BAIL();        sprintf(p +  0u, "%08lx", static_cast<long unsigned>(p32[0]));        sprintf(p + 16u, "%08lx", static_cast<long unsigned>(p32[1]));        return true;    } Of course, you wouldn't be able to store one of these lambdas inside a normal 'std::function', you'd need to store it inside a 'std::long_return_function' instead. A few important points: (1) The return type of a 'long return lambda', if not omitted, must be implicitly-convertible to the return type of the enclosing function. (2) You cannot analyse the return value from a 'long return lambda' inside the enclosing function. For example the initialisation of a variable inside the enclosing function cannot involve the invocation of a 'long return lambda', so the following isn't valid:    int MyFunc(void)    {        auto monkey = []()->long return { return 5; }        int i = monkey();  // ill-formed - compiler must issue diagonstic    } (3) However you can analyse the return value higher up the function call hierarchy:    int Func2(void)    {        auto Bail = []() -> long return int { return 5; }        // int i = Bail();  - This would be invalid        Bail();    }    int Func(void)    {        int i = Func2();  // This is valid    } -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-04-11 13:36:31