You don't want to count % or the number of scopes, especially if some scopes don't have separate braces.
-----Ursprüngliche Nachricht-----
Von: Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org>
Gesendet: Sa 23.05.2026 09:37
Betreff: Re: [std-proposals] return value lives until end of scope
An: std-proposals@lists.isocpp.org;
CC: Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>;
On Thursday, May 21, 2026, Jonathan Wakely wrote:Yeah, I don't want spooky changes to the lifetime model and how it interacts with scopes to happen implicitly based on something far away on the function declaration. If somebody adds __persistent to a declaration, it silently changes the meaning of existing callers. No thanks.What if we were to move the 'mark' to the calling site. Perhaps a unary operator? So the following:int main(void){%async(Func);}would be the same as:int main(void){auto dummy = async(Func);}Of course this begs the question, what about loops?for ( unsigned i = 0u; i < N; ++i ) %async(Func);Well I think in the above line, the scope of the return value should be to the nearest preceding {, meaning that after the loop has finished, you have N objects on the stack as the N threads run concurrently (implemented by the compiler by calling 'alloca' inside the loop with linked list).But what if the loop has a curly-braced body?for ( unsigned i = 0u; i < N, ++i ){%async(Func);Log("new thread started");}In the above code, the return value from 'async' will be destroyed at the }, meaning the threads would run consecutively rather than concurrently. If you want it to persist up one level, then you double it:for ( unsigned i = 0u; i < N, ++i ){%%async(Func);Log("new thread started");}And if you want it to persist up another level above that, you triple it:for ( unsigned i = 0u; i < ROWS; ++i ){for ( unsigned j = 0u; j < COLS; ++j ){%%%async(Func);Log("new thread started");}}This could allow some really cool stuff to happen, for instance let's say we were to give 'std::mutex' a method as follows:lock_guard<mutex> mutex::autolock(void)We could then lock a mutex as follows:mutex m;int main(void){m.%autolock(); // or: %m.autolock() ?DoSomething();}We could expand the scope of the lock:int main(void){if ( a ){if ( b || c ){m.%%%autolock(); // or: %%%m.autolock() ?}}DoSomething();}In any function body that contains use of %% or %%%, the compiler would have to allocate space on the stack upon entering the function in order to manage the might-or-might-not-be-created objects. This would involve the use of 'alloca' along with memory addresses of destructors that need to run.-- Std-Proposals mailing list Std-Proposals@lists.isocpp.org https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals