当我编译以下代码时,我收到警告(https://godbolt.org/z/Tx7v6jWf1):
void foo() {
int _;
// warning: name-independent declarations only available with
// '-std=c++2c' or '-std=gnu++2c' [-Wc++26-extensions]
int _;
}
C++26 中的
_
变量究竟发生了什么变化,以及什么是 名称独立声明?
P2169:一个没有名字的漂亮占位符已被C++26接受,这使得
_
在以下上下文中变得特殊:
int _
)auto [x, _]
)[_ = 0] {}
)struct S { int _; }
)在这种情况下,
_
使声明与名称无关。
_
抑制警告标准说:
推荐做法:实现不应发出关于使用或未使用名称无关声明的警告。
这与
[dcl.attr.unused] p4中对
[[maybe_unused]]
的建议非常相似。
通常,您会收到未使用变量的警告(GCC 中的 -Wunused
),但 _
和 [[maybe_unused]]
会抑制这种情况。从历史上看,开发人员经常使用 _
作为“占位符”未使用的东西,所以这只是标准化现有的做法。
_
可以多次声明此外,与名称无关的声明不能可能发生冲突。 简而言之,您可以多次声明
_
。但是,名称查找不能有歧义。
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
}
此代码取自 [basic.scope.scope] 示例 3。
请注意,
_
还与 using
声明有一些特殊的交互。请参阅 [namespace.udecl] p10 了解更多详细信息。
_
不是同一实体即使有外部链接,两个
_
也不被视为同一实体:
// a.cpp
int _ = 0;
// b.cpp
int _ = 0;
链接后,该程序就可以了。 对于
_
以外的任何名称,这都会给您带来“多重定义”链接器错误。
另请参阅 [basic.link] p8。
在撰写本文时,只有 GCC 14 和 Clang 18 支持此功能。 有关更多信息,请参阅C++26 编译器支持。
__cpp_placeholder_variables
:
#if __cpp_placeholder_variables >= 202306L