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@lists.isocpp.org>
Gesendet: Di 11.04.2023 15:17
Betreff: [std-proposals] long return lambda
An: std-proposals <std-proposals@lists.isocpp.org>;
CC: Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>;
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@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals