C++ Logo

std-proposals

Advanced search

Re: [std-proposals] A new C++ keyword: forget

From: Connor Song <perdixky_at_[hidden]>
Date: Wed, 12 Aug 2026 10:33:27 +0800
Hi Ville,

I am not convinced that spelling this as

std::redact(x);

is a good direction if redact is not actually a library entity.

static_assert does not seem like a particularly good analogy here.
static_assert may syntactically resemble a function call, but static_assert
is a keyword and the grammar explicitly recognizes a
static-assert-declaration. There is no ambiguity about whether name lookup,
overload resolution, taking its address, a using-declaration, etc. apply to
it.

With std::redact(x), however, the spelling strongly suggests an ordinary
qualified name referring to an entity in namespace std.

If it is instead recognized specially by the parser and changes
core-language rules such as name lookup, reachability, or whether a later
declaration is well-formed, then I think the syntax is somewhat misleading.

For example, what should these mean?

using std::redact;

auto p = &std::redact;

std::redact<int>;

namespace foo {
    void redact(int&);
}

foo::redact(x); // ordinary function
std::redact(x); // core-language construct?

Presumably most or all of the first three would simply be invalid because
std::redact is not actually a name denoting a function. But that is exactly
what feels strange to me: it has the lexical appearance of a qualified
library name while deliberately not obeying the normal rules associated
with one.

The proposed operation also seems fundamentally core-language in nature. If

int x;
redact x;
++x; // ill-formed
double x; // perhaps also ill-formed

affects lookup, declaration matching, shadowing, and scope semantics, then
I would expect the syntax to make that fact visible.

A keyword, or possibly a contextual keyword, seems more natural to me:

redact x;

or perhaps

redact(x);

where redact is explicitly part of the grammar.

A contextual keyword might also address the source-compatibility concern
that motivated avoiding a new keyword in the first place, without making a
core-language construct look like a standard-library function.

Best,
Connor

Ville Voutilainen via Std-Proposals <std-proposals_at_[hidden]>
于2026年8月12日周三 08:15写道:

> On Wed, 12 Aug 2026 at 03:08, Marcin Jaczewski
> <marcinjaczewski86_at_[hidden]> wrote:
> > if this is `std::redact` this means its normal function as it can't be
> > a keyword, right?
>
> It's not a normal function. It's a language construct recognized by
> the compiler. And despite
> being spelled like a function, it can be a declaration, like static_assert
> is.
>
> > This means it will need some tag to mark this behavior like:
> > void redact([[redact]] auto& val) {}
>
> No.
>
> > class Foo
> > {
> > int i;
> > void dispose() [[redact]]; //as it refer to `this`
> > }
> > int main()
> > {
> > Foo a;
> > a.i = 1;
> > a.dispose();
> > //a..i = 2; //error
> > }
>
> Well.. the idea here is to redact names. Not objects. Now you're
> entering a territory
> where we need some sort of flow analysis.
>
> > Another thing we could simply use:
> > int a = 3;
> > [[redact]] a;
>
> If our construct is a declaration, you can just do
>
> int a = 3;
> std::redact(a);
>
> regardless of what the scope of a is.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2026-08-12 02:33:45