P2169: A nice placeholder with no name has been accepted into C++26, which makes _
special in the following contexts:
- local variables (e.g.
int _
)
- local structured bindings (e.g.
auto [x, _]
)
- init-captures (e.g.
[_ = 0] {}
)
- non-static data members of other than an anonymous union (e.g.
struct S { int _; }
)
In such contexts, _
makes the declaration name-independent.
_
suppresses warnings
The standard says:
Recommended practice: Implementations should not emit a warning that a name-independent declaration is used or unused.
This is very similar to the recommendation for [[maybe_unused]]
in [dcl.attr.unused] p4.
Normally, you would get a warning for unused variables (-Wunused
in GCC), but _
and [[maybe_unused]]
suppress this.
Historically, developers have used _
as a "placeholder" for unused things, so this is just standardizing existing practice.
_
can be declared multiple times
Furthermore, name-independent declarations cannot potentially conflict.
In short, you can declare _
multiple times. However, name lookup cannot be ambiguous.
void g() {
int _;
_ = 0; // OK, and warning is not recommended
int _; // OK, name-independent declaration does not potentially conflict with the first _
_ = 0; // error: two non-function declarations in the lookup set
}
This code is taken from [basic.scope.scope] example 3.
Note that _
also has some special interactions with using
declarations. See [namespace.udecl] p10 for more details.
Two _
are not the same entity from the linker's perspective
Even with external linkage, two _
are not considered the same entity:
// a.cpp
int _ = 0;
// b.cpp
int _ = 0;
When linked, this program is OK.
For any name other than _
, this would give you a "multiple definitions" linker error.
See also [basic.link] p8.
Compiler Support
Only GCC 14 and Clang 18 support this feature at the time of writing.
See C++26 compiler support for more.
If you need to test for support, test for __cpp_placeholder_variables
:
#if __cpp_placeholder_variables >= 202306L
std::ignore
would have been so much better and be more consistent. But now they want to add this mess.static
changes how_
is interpreted completely, you are allowed to read and write to that variable, you are allowed to have multiple otherwise conflicting declarations but only if not reading/asigning values!?! That is the opposite of what the proposal was supposed to solve. This will be the source of so many problems again. – Interstate