Date: Thu, 27 Aug 2026 20:00:07 +0200
On 2026-08-27 18:00, Ted Lyngmo via Std-Proposals wrote:
> 2026-08-27 00:46, Henry Skoglund:
>> On 2026-08-27 00:03, Ted Lyngmo via Std-Proposals wrote:
>>>
>>> If we go ahead with the idea then perhaps an alternative to a
>>> `std::redact`/`std::unredact` pair of functions with magic
>>> properties would be to take inspiration from clang's "consumable"
>>> attributes?
>>>
>>
>> Hi, I like that terminology "consumed", it reminds me of the original
>> idea for redact(): to prevent reuse of variables in typically larger
>> functions maintained by several people:
>> int munge(int raw)
>> {
>> int cooked = raw * 4711;
>> ...
>> int cookagain = raw; // should have used cooked (we're done
>> with raw, it's "consumed")
>> }
>>
>> However that attribute can only be applied to structs and classes,
>> right? I would like to be able to redact all types of variables.
> I haven't tried them out that much. Perhaps it's not possible to make
> an `int` consumable and I think I'd buy the reasoning behind that even
> though consistency is nice.
>
> I had a similar idea to the "consumable" track with only two
> attributes, [[redact]] and [[unredact]]. Something along these lines:
>
> class string {
> public:
> string([[redact]] string&&);
>
> string& operator=([[unredact]] this string& self,
> [[redact]] string&& other );
>
> void clear([[unredact]] this string& self);
> };
>
> The move assignment operator would in this case unredact *this and
> redact whatever we "move from". It'd require reference tracking to
> survive through `std::move` and references bound to an lvalue. The
> lvalue and all named references to it should preferably be redacted
> all at once, no matter what name we used as an argument to the operator.
>
> An unredacting function (member or non-member) would have to follow
> some rules:
>
> void func([[unredact]] string& str) {
> // The variable (the lvalue + references to it) passed to func is
> // unredacted while `str` inside the function is redacted upon entry.
> //
> // compilation error if
> // - The first str member used is not an unredacting member function
> // - The function can return with str redacted (all branches must be
> // proven to lead to leaving the function with str unredacted,
> // exception handling may be tricky)
> // - I had some other thoughts about rules but forgot them :-)
> }
>
> Perhaps a side track from the original idea but I think it's
> interesting to reason about what kind of redaction logic we could get
> in place without touching too much of existing user-code. If it would
> be possible to make the std::string API as above, the idea is that
> code that already uses `std::string` correctly would not need to be
> touched.
>
> Br,
> Ted
I think between gcc's poison pragma, clang's consumable attribute and
clang-tidy's tracking of suspicious movements, you can see a pattern
here, for which I think std::redact() could fit in.
And please no resurrections, unpoisoning or unredacting. That I think
almost always can be done anyway by opening another scope and shadow
variable. https://memory-alpha.fandom.com/wiki/He%27s_dead,_Jim
> 2026-08-27 00:46, Henry Skoglund:
>> On 2026-08-27 00:03, Ted Lyngmo via Std-Proposals wrote:
>>>
>>> If we go ahead with the idea then perhaps an alternative to a
>>> `std::redact`/`std::unredact` pair of functions with magic
>>> properties would be to take inspiration from clang's "consumable"
>>> attributes?
>>>
>>
>> Hi, I like that terminology "consumed", it reminds me of the original
>> idea for redact(): to prevent reuse of variables in typically larger
>> functions maintained by several people:
>> int munge(int raw)
>> {
>> int cooked = raw * 4711;
>> ...
>> int cookagain = raw; // should have used cooked (we're done
>> with raw, it's "consumed")
>> }
>>
>> However that attribute can only be applied to structs and classes,
>> right? I would like to be able to redact all types of variables.
> I haven't tried them out that much. Perhaps it's not possible to make
> an `int` consumable and I think I'd buy the reasoning behind that even
> though consistency is nice.
>
> I had a similar idea to the "consumable" track with only two
> attributes, [[redact]] and [[unredact]]. Something along these lines:
>
> class string {
> public:
> string([[redact]] string&&);
>
> string& operator=([[unredact]] this string& self,
> [[redact]] string&& other );
>
> void clear([[unredact]] this string& self);
> };
>
> The move assignment operator would in this case unredact *this and
> redact whatever we "move from". It'd require reference tracking to
> survive through `std::move` and references bound to an lvalue. The
> lvalue and all named references to it should preferably be redacted
> all at once, no matter what name we used as an argument to the operator.
>
> An unredacting function (member or non-member) would have to follow
> some rules:
>
> void func([[unredact]] string& str) {
> // The variable (the lvalue + references to it) passed to func is
> // unredacted while `str` inside the function is redacted upon entry.
> //
> // compilation error if
> // - The first str member used is not an unredacting member function
> // - The function can return with str redacted (all branches must be
> // proven to lead to leaving the function with str unredacted,
> // exception handling may be tricky)
> // - I had some other thoughts about rules but forgot them :-)
> }
>
> Perhaps a side track from the original idea but I think it's
> interesting to reason about what kind of redaction logic we could get
> in place without touching too much of existing user-code. If it would
> be possible to make the std::string API as above, the idea is that
> code that already uses `std::string` correctly would not need to be
> touched.
>
> Br,
> Ted
I think between gcc's poison pragma, clang's consumable attribute and
clang-tidy's tracking of suspicious movements, you can see a pattern
here, for which I think std::redact() could fit in.
And please no resurrections, unpoisoning or unredacting. That I think
almost always can be done anyway by opening another scope and shadow
variable. https://memory-alpha.fandom.com/wiki/He%27s_dead,_Jim
Received on 2026-08-27 18:00:17
