Date: Thu, 13 Aug 2026 14:09:47 +0200
As I understand it, and I hope I'll be corrected if I get the details
wrong, the language already starts new scopes for each declaration.
(The exact start of the scope is from when the type of the object is
known and the identifier is declared.)
The starting scopes are the same for :
int a;
// Here we have a scope containing "a"
int b;
// Here we have a scope containing "a" and "b"
and
int a;
// Here we have a scope containing "a"
{
int b;
// Here we have a scope containing "a" and "b"
}
are the same.
Braced blocks affect the end of the scopes - in the second example, the
scope of "b" ends at the close brace while the scope of "a" continues.
I will try to answer your specific questions.
What is it that the user really wants? That's very much dependent on
the user! I want the changes I described, but I can't really speak for
anyone else. Yes, more convenient copy-and-paste is one use-case for
re-using identifier names, but it's not the only one.
Having lots of local variables can definitely be a cost if they have
non-trivial destructors - typically they all need to stay on the stack
until the end of their lifetimes so that the can be destructed in
correct reverse order. But that applies whether they have different
names, or the same names shadowing each other (using extra braced blocks
in current C++, or skipping that need with my suggested change). On the
other hand, if the destructors are trivial or the compiler can see that
they can have their order re-arranged without affecting semantics, the
the stack space (and registers) can be re-used. This all applies today
- nothing about my suggestions change that. In particular, I am not
suggesting that declaring a new object of the same name, shadowing an
existing object, should shorten the lifetime or trigger the destructor
of the previous object. Doing so would make the new version different
from existing code with extra braced blocks or different identifier
names, and that would be (IMHO) counter-intuitive.
As a related thought, it might be nice to be able to declare a
destructor to be "asynchronous" or "unordered" in some way. By that I
mean that instead of the destructor being run in deterministic order at
end of the object's lifetime, the compiler can run it early - as soon as
lifetime analysis of the code shows that the object is no longer in use.
That could improve efficiency when you have lots of local variables
with destructors, regardless of how they are named and independent of my
suggested changes. It might make exception handling more complex in
some cases, but this would be an optional optimisation for the compiler
- it would always be free to postpone the "asynchronous" destructors to
their current deterministic position.
As with most new features, my suggestions (especially re-usable
identifiers) would have the potential for writing new bugs and confusing
code as well as clearer and neater code.
On 13/08/2026 12:41, Sebastian Wittmeier via Std-Proposals wrote:
> I think it is possible to start a new scope after each instruction and
> still have a syntactically and semantically correct program as you have
> shown. That gives a natural meaning and opening to shadow variables.
>
> But is it what the user really wants (if they care)?
>
> - Regarding object lifetime: Delay destruction until the end of the
> scope. Having many more objects 'flying around' than names in the
> function. I tend to prefer, if the original variable is destructed at
> that time.
>
> - Why reuse the names? That makes copy&paste easier. Or similar
> blocks, e.g. for return codes and error handling. But also leads to
> potential errors. A lot of dynamically typed languages allow it
>
> -----Ursprüngliche Nachricht-----
> *Von:* David Brown via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Mi 12.08.2026 09:52
> *Betreff:* Re: [std-proposals] A new C++ keyword: forget
> *An:* std-proposals_at_[hidden];
> *CC:* David Brown <david.brown_at_[hidden]>;
> We could come a very long way with all this with three changes /
> additions to the language :
>
> 1. Allow a new variable declaration to shadow an exiting one,
> starting a
> new scope without having to open a new block. Thus :
>
> int a = 1;
> do_something(a);
> int a = 2;
> do_something_else(a);
> double a = 3;
> do_another_thing(a);
>
> would mean the same as :
>
> int a = 1;
> do_something(a);
> {
> int a = 2;
> do_something_else(a);
> {
> double a = 3;
> do_another_thing(a);
> }
> }
>
>
wrong, the language already starts new scopes for each declaration.
(The exact start of the scope is from when the type of the object is
known and the identifier is declared.)
The starting scopes are the same for :
int a;
// Here we have a scope containing "a"
int b;
// Here we have a scope containing "a" and "b"
and
int a;
// Here we have a scope containing "a"
{
int b;
// Here we have a scope containing "a" and "b"
}
are the same.
Braced blocks affect the end of the scopes - in the second example, the
scope of "b" ends at the close brace while the scope of "a" continues.
I will try to answer your specific questions.
What is it that the user really wants? That's very much dependent on
the user! I want the changes I described, but I can't really speak for
anyone else. Yes, more convenient copy-and-paste is one use-case for
re-using identifier names, but it's not the only one.
Having lots of local variables can definitely be a cost if they have
non-trivial destructors - typically they all need to stay on the stack
until the end of their lifetimes so that the can be destructed in
correct reverse order. But that applies whether they have different
names, or the same names shadowing each other (using extra braced blocks
in current C++, or skipping that need with my suggested change). On the
other hand, if the destructors are trivial or the compiler can see that
they can have their order re-arranged without affecting semantics, the
the stack space (and registers) can be re-used. This all applies today
- nothing about my suggestions change that. In particular, I am not
suggesting that declaring a new object of the same name, shadowing an
existing object, should shorten the lifetime or trigger the destructor
of the previous object. Doing so would make the new version different
from existing code with extra braced blocks or different identifier
names, and that would be (IMHO) counter-intuitive.
As a related thought, it might be nice to be able to declare a
destructor to be "asynchronous" or "unordered" in some way. By that I
mean that instead of the destructor being run in deterministic order at
end of the object's lifetime, the compiler can run it early - as soon as
lifetime analysis of the code shows that the object is no longer in use.
That could improve efficiency when you have lots of local variables
with destructors, regardless of how they are named and independent of my
suggested changes. It might make exception handling more complex in
some cases, but this would be an optional optimisation for the compiler
- it would always be free to postpone the "asynchronous" destructors to
their current deterministic position.
As with most new features, my suggestions (especially re-usable
identifiers) would have the potential for writing new bugs and confusing
code as well as clearer and neater code.
On 13/08/2026 12:41, Sebastian Wittmeier via Std-Proposals wrote:
> I think it is possible to start a new scope after each instruction and
> still have a syntactically and semantically correct program as you have
> shown. That gives a natural meaning and opening to shadow variables.
>
> But is it what the user really wants (if they care)?
>
> - Regarding object lifetime: Delay destruction until the end of the
> scope. Having many more objects 'flying around' than names in the
> function. I tend to prefer, if the original variable is destructed at
> that time.
>
> - Why reuse the names? That makes copy&paste easier. Or similar
> blocks, e.g. for return codes and error handling. But also leads to
> potential errors. A lot of dynamically typed languages allow it
>
> -----Ursprüngliche Nachricht-----
> *Von:* David Brown via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Mi 12.08.2026 09:52
> *Betreff:* Re: [std-proposals] A new C++ keyword: forget
> *An:* std-proposals_at_[hidden];
> *CC:* David Brown <david.brown_at_[hidden]>;
> We could come a very long way with all this with three changes /
> additions to the language :
>
> 1. Allow a new variable declaration to shadow an exiting one,
> starting a
> new scope without having to open a new block. Thus :
>
> int a = 1;
> do_something(a);
> int a = 2;
> do_something_else(a);
> double a = 3;
> do_another_thing(a);
>
> would mean the same as :
>
> int a = 1;
> do_something(a);
> {
> int a = 2;
> do_something_else(a);
> {
> double a = 3;
> do_another_thing(a);
> }
> }
>
>
Received on 2026-08-13 12:09:56
