Date: Wed, 10 Dec 2025 16:19:41 -0500
I'd like to summarize a few points in case they have been missed.
`undecl`, to some, seems like it is solving half of a problem
It might be good if there were the following two versions of it instead:
undecl(destroy) // as the undecl author envisioned it
undecl(hide) // as it is related to shadowing but not shadowing
Likely neither `destroy` nor `hide` should be the default. So don't waste
10 years debating the default when you can have 10 years of explicit usage
telling us what the default will be.
The following does not involve any shadowing though it is related to
shadowing and undecl(hide).
string_view a = string{};// immediate dangling
//or
span a = vector{};// immediate dangling
The defensive programming workaround is as follows.
struct dename{}; // simply any 0 size tag type without any functionality
will do
...
...
...
vector some_name_we_will_only_use_once{};
span a = some_name_we_will_only_use_once;
{
dename some_name_we_will_only_use_once;
// MOVE all other code into this block
}
OR with undecl(hide)
vector some_name_we_will_only_use_once{};
span a = some_name_we_will_only_use_once;
undecl(hide) some_name_we_will_only_use_once;
NOTE: The current status quo of `span a = vector{};` is that programmers
either immediately dangle OR have to write verbose code OR worse lazily
have superfluous aliases out there contributing to invalidation,
concurrency errors and/or harder to understand code.
Making `span a = vector{};` NOT immediate dangling BY allowing lifetime
extension to apply to all pure alias types instead of just references
DOESN'T break any existing code which isn't already immediately dangling
and it doesn't require any new keywords or annotations. Rather it has
numerous benefits.
This would remove an embarrassing form of dangling associated with the
creation of temporaries.
This would remove an inconsistency that lifetime extension works on
reference but not reference like types.
This allows the programmer to better manage invalidation without having to
create superfluous aliases that only further enable invalidation.
On Wed, Dec 10, 2025 at 3:14 PM Simon Schröder via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
>
> > On Dec 10, 2025, at 9:46 AM, David Brown via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> > 1. Copy-and-paste code (redeclaration without undecl) :
> This variant I don’t really like. It would be too easy to accidentally
> shadow a variable. If I have working code and I accidentally redeclare a
> variable (possibly with the same type) right between the declaration of the
> old variable and the previously last use of the variable, I will break that
> code without a compiler error. In my opinion it is a good thing to have
> compiler errors when you try to do something stupid. (Maybe we could allow
> shadowing without undecl and then unshadow using undecl. Anyway, it would
> be much better if you’d had to be explicit about shadowing, e.g. with an
> attribute [[shadow]]. Nothing accidental about that.) BTW, if you want a
> variable you can shadow, use _.
> >
> > 2. Explicitly ending the lifetime of a variable and making it unusable:
> >
> Other languages (e.g. Rust) use the ‘keyword’ ‘drop’ for this. I’m not
> sure if ‘drop’ will collide with common variable names (or more likely with
> function names). ‘undecl’ certainly looks like it is not yet used in any
> C++ code. As has been replied already: std::optional already allows to end
> the lifetime of a variable early (but without the added “benefit” of being
> able to reuse its name (if it’s not the same type)).
> >
> > 3. Const-locking identifiers (redeclaration without undecl) :
> >
> This is a nice idea I could get behind.
> >
> > auto x = get_x();
> > change_x(&x);
> > const auto x = x;
> > change_x(&x); // Compile-time error
> >
> Currently syntax like the line
> const auto x = x;
> would first declare a variable ‘x’ and then assign it to itself. We should
> have some other syntax for this feature. It is currently already possible
> to write this kind of buggy code if ‘x’ comes from an outer scope. There is
> no reason for this to behave differently if we shadow an ‘x’ from the same
> scope. And certainly someone is “relying” on this bug and we’d break
> someone’s code if we fix this.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
`undecl`, to some, seems like it is solving half of a problem
It might be good if there were the following two versions of it instead:
undecl(destroy) // as the undecl author envisioned it
undecl(hide) // as it is related to shadowing but not shadowing
Likely neither `destroy` nor `hide` should be the default. So don't waste
10 years debating the default when you can have 10 years of explicit usage
telling us what the default will be.
The following does not involve any shadowing though it is related to
shadowing and undecl(hide).
string_view a = string{};// immediate dangling
//or
span a = vector{};// immediate dangling
The defensive programming workaround is as follows.
struct dename{}; // simply any 0 size tag type without any functionality
will do
...
...
...
vector some_name_we_will_only_use_once{};
span a = some_name_we_will_only_use_once;
{
dename some_name_we_will_only_use_once;
// MOVE all other code into this block
}
OR with undecl(hide)
vector some_name_we_will_only_use_once{};
span a = some_name_we_will_only_use_once;
undecl(hide) some_name_we_will_only_use_once;
NOTE: The current status quo of `span a = vector{};` is that programmers
either immediately dangle OR have to write verbose code OR worse lazily
have superfluous aliases out there contributing to invalidation,
concurrency errors and/or harder to understand code.
Making `span a = vector{};` NOT immediate dangling BY allowing lifetime
extension to apply to all pure alias types instead of just references
DOESN'T break any existing code which isn't already immediately dangling
and it doesn't require any new keywords or annotations. Rather it has
numerous benefits.
This would remove an embarrassing form of dangling associated with the
creation of temporaries.
This would remove an inconsistency that lifetime extension works on
reference but not reference like types.
This allows the programmer to better manage invalidation without having to
create superfluous aliases that only further enable invalidation.
On Wed, Dec 10, 2025 at 3:14 PM Simon Schröder via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
>
> > On Dec 10, 2025, at 9:46 AM, David Brown via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> > 1. Copy-and-paste code (redeclaration without undecl) :
> This variant I don’t really like. It would be too easy to accidentally
> shadow a variable. If I have working code and I accidentally redeclare a
> variable (possibly with the same type) right between the declaration of the
> old variable and the previously last use of the variable, I will break that
> code without a compiler error. In my opinion it is a good thing to have
> compiler errors when you try to do something stupid. (Maybe we could allow
> shadowing without undecl and then unshadow using undecl. Anyway, it would
> be much better if you’d had to be explicit about shadowing, e.g. with an
> attribute [[shadow]]. Nothing accidental about that.) BTW, if you want a
> variable you can shadow, use _.
> >
> > 2. Explicitly ending the lifetime of a variable and making it unusable:
> >
> Other languages (e.g. Rust) use the ‘keyword’ ‘drop’ for this. I’m not
> sure if ‘drop’ will collide with common variable names (or more likely with
> function names). ‘undecl’ certainly looks like it is not yet used in any
> C++ code. As has been replied already: std::optional already allows to end
> the lifetime of a variable early (but without the added “benefit” of being
> able to reuse its name (if it’s not the same type)).
> >
> > 3. Const-locking identifiers (redeclaration without undecl) :
> >
> This is a nice idea I could get behind.
> >
> > auto x = get_x();
> > change_x(&x);
> > const auto x = x;
> > change_x(&x); // Compile-time error
> >
> Currently syntax like the line
> const auto x = x;
> would first declare a variable ‘x’ and then assign it to itself. We should
> have some other syntax for this feature. It is currently already possible
> to write this kind of buggy code if ‘x’ comes from an outer scope. There is
> no reason for this to behave differently if we shadow an ‘x’ from the same
> scope. And certainly someone is “relying” on this bug and we’d break
> someone’s code if we fix this.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-12-10 21:19:57
