Date: Tue, 11 Aug 2026 21:05:12 +0200
This reminds me (in case you are continuing with the proposal): You should discuss if once a variable has been poisoned, if the same name can be reused for a different variable.
> On Aug 11, 2026, at 7:59 PM, Henry Skoglund via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On 2026-08-10 19:06, Udo Steinbach via Std-Proposals wrote:
>> Reason? Benefit? Use case?
>>
>> I get the impression that more and more people here want to add yet another safety belt for every conceivable scenario—one that’s supposed to protect the user from something, but which the user has to fasten themselves. Benefit: Zero. If a security mechanism works only by introducing another protocol that must be followed manually, the benefit is negative.
>
>> On 2026-08-10 14:26, Ville Voutilainen via Std-Proposals wrote:
>>> On Sun, 9 Aug 2026 at 23:35, Jarrad Waterloo via Std-Proposals
>>> <std-proposals_at_[hidden]> wrote:
>>> Concerning voiding/deleting/forgetting/poisoning/shadowing specific overloads, it has to do with "safe subset of a superset" not just at the language level but at the library level.
>>> I use an undesired overload to first create one or more functions that I do want and then I hide the undesired function to prevent me from using it further.
>>>
>>> #include <some-std-library>
>>> #include <3rd-party-utility-library-that-uses-that-std-library>
>>> #include <hide-portions-of-std-library> // NOTE: order matters ... consider all one gains by easily copying 3 lines of code
>>>
>>> ...
>>>
>>> While there are cases where proxying is necessary, this could be a good/easy alternative because it allows one to remove specific overloads without having to proxy an entire library.
>>>
>>> Consider this hyper specific example,
>>>
>>> Instead of creating a non invalidating view of a vector, or any class really, which requires creating a new type and duplicating all of the desired overloads and transitive dependencies, while omitting all of the undesirable overloads, one could just hide the methods that invalidate from one's own code.
>>>
>>> Here is another use case, with all of the safe operations that can be performed on std::optional<T> do I really want access to the less safe operations.
>>>
>>> This isn't just a per programmer tool but has to do with standards that team leads enforce upon their teams to improve code quality.
>> I'm not convinced it's the best of ideas to bring wishes for
>> controlling overload resolution into this discussion.
>> Being able to say that a name is poisoned for name-lookup for the
>> remaining scope is seemingly very reasonable, and has very
>> clear example use cases (like poisoning the name of a moved-from
>> entity). Overload resolution control is something quite different,
>> and probably wouldn't share the property of allowing the uses before a
>> certain point but not after, and would likely be just "don't
>> allow certain uses at all in this scope). While it could be argued
>> that that's just a matter where you place the poisoning, there's
>> also the matter that such overload poisoning would be better done in
>> scopes wider than a function block scope, like per-namespace
>> or per-class. Or even per-TU. It's eerily close to a proper profile,
>> and poisoning name lookups for individual variables seems less so
>> to me. I can of course be convinced otherwise, this is not a final
>> analysis conclusion, just a current take.
>
> Thanks for all the replies!
>
> Re. use case: say you have a reasonably large (and old) codebase with a function:
> void munge(double raw)
> {
> auto cooked = raw * tweakfactor;
> ...
> the cooked chap is used in the rest of the function, until a revision comes along and adds some code at the end:
> auto newvalue = raw;
> ...
>
> This new code shouldn't have picked up on raw, it should have used cooked. I've been bitten a few times by these kinds of bugs so I wanted some way to cause an error, first idea was some kind of function template:
>
> auto cooked = std::burn_after_reading<raw> * tweakfactor;
>
> I didn't know about the poison #pragma (until now), I like that term "to poison" it's very succinct :-) And that's what I wanted the template to do. I couldn't figure how, though. So instead I came up with the idea of the "forget" keyword.
>
> Then as a cherry on top, I realized you can reuse that "forget" keyword to being able to abolish *all* uses of say strcpy() inside a TU, regardless if the forget statement arrives before or after any strcpy() calls. I.e. a way to blacklisting a function.
>
> Maybe there's also some benefit of being able to poison types? E.g.
> forget MyType, std::string;
> or
> forget ::; // poisons everything, scary...
>
> Rgrds Henry
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> On Aug 11, 2026, at 7:59 PM, Henry Skoglund via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On 2026-08-10 19:06, Udo Steinbach via Std-Proposals wrote:
>> Reason? Benefit? Use case?
>>
>> I get the impression that more and more people here want to add yet another safety belt for every conceivable scenario—one that’s supposed to protect the user from something, but which the user has to fasten themselves. Benefit: Zero. If a security mechanism works only by introducing another protocol that must be followed manually, the benefit is negative.
>
>> On 2026-08-10 14:26, Ville Voutilainen via Std-Proposals wrote:
>>> On Sun, 9 Aug 2026 at 23:35, Jarrad Waterloo via Std-Proposals
>>> <std-proposals_at_[hidden]> wrote:
>>> Concerning voiding/deleting/forgetting/poisoning/shadowing specific overloads, it has to do with "safe subset of a superset" not just at the language level but at the library level.
>>> I use an undesired overload to first create one or more functions that I do want and then I hide the undesired function to prevent me from using it further.
>>>
>>> #include <some-std-library>
>>> #include <3rd-party-utility-library-that-uses-that-std-library>
>>> #include <hide-portions-of-std-library> // NOTE: order matters ... consider all one gains by easily copying 3 lines of code
>>>
>>> ...
>>>
>>> While there are cases where proxying is necessary, this could be a good/easy alternative because it allows one to remove specific overloads without having to proxy an entire library.
>>>
>>> Consider this hyper specific example,
>>>
>>> Instead of creating a non invalidating view of a vector, or any class really, which requires creating a new type and duplicating all of the desired overloads and transitive dependencies, while omitting all of the undesirable overloads, one could just hide the methods that invalidate from one's own code.
>>>
>>> Here is another use case, with all of the safe operations that can be performed on std::optional<T> do I really want access to the less safe operations.
>>>
>>> This isn't just a per programmer tool but has to do with standards that team leads enforce upon their teams to improve code quality.
>> I'm not convinced it's the best of ideas to bring wishes for
>> controlling overload resolution into this discussion.
>> Being able to say that a name is poisoned for name-lookup for the
>> remaining scope is seemingly very reasonable, and has very
>> clear example use cases (like poisoning the name of a moved-from
>> entity). Overload resolution control is something quite different,
>> and probably wouldn't share the property of allowing the uses before a
>> certain point but not after, and would likely be just "don't
>> allow certain uses at all in this scope). While it could be argued
>> that that's just a matter where you place the poisoning, there's
>> also the matter that such overload poisoning would be better done in
>> scopes wider than a function block scope, like per-namespace
>> or per-class. Or even per-TU. It's eerily close to a proper profile,
>> and poisoning name lookups for individual variables seems less so
>> to me. I can of course be convinced otherwise, this is not a final
>> analysis conclusion, just a current take.
>
> Thanks for all the replies!
>
> Re. use case: say you have a reasonably large (and old) codebase with a function:
> void munge(double raw)
> {
> auto cooked = raw * tweakfactor;
> ...
> the cooked chap is used in the rest of the function, until a revision comes along and adds some code at the end:
> auto newvalue = raw;
> ...
>
> This new code shouldn't have picked up on raw, it should have used cooked. I've been bitten a few times by these kinds of bugs so I wanted some way to cause an error, first idea was some kind of function template:
>
> auto cooked = std::burn_after_reading<raw> * tweakfactor;
>
> I didn't know about the poison #pragma (until now), I like that term "to poison" it's very succinct :-) And that's what I wanted the template to do. I couldn't figure how, though. So instead I came up with the idea of the "forget" keyword.
>
> Then as a cherry on top, I realized you can reuse that "forget" keyword to being able to abolish *all* uses of say strcpy() inside a TU, regardless if the forget statement arrives before or after any strcpy() calls. I.e. a way to blacklisting a function.
>
> Maybe there's also some benefit of being able to poison types? E.g.
> forget MyType, std::string;
> or
> forget ::; // poisons everything, scary...
>
> Rgrds Henry
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-08-11 19:05:32
