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
>
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
