c++ - gcc >=10.1 和 clang 不检测未使用但设置 lambda
问题描述
考虑以下程序:
template <unsigned int I>
int f(int x)
{
auto task = [&]() { ++x; };
if constexpr (I == 0) {
task();
}
return x;
}
int main()
{
f<1>(3);
}
在 gcc 9.3 上编译时-std=c++17 -Wall -pedantic
会发出警告
warning: variable 'task' set but not used [-Wunused-but-set-variable]
4 | auto task = [&]() { ++x; };
但是对于较新的 gcc 版本,不会出现这样的警告。请注意,根据手册,-Wunused-but-set-variable
由 启用-Wall
。
同样使用clang,不会出现这样的警告。
在godbolt上测试它。
这是编译器的缺点,还是需要/预期这种行为(缺乏警告)?
解决方案
考虑这个稍微修改过的代码:
template <unsigned int I>
int f(int x)
{
auto task = [&]() { ++x; };
if constexpr (I == 0) {
task();
}
return x;
}
int main()
{
f<0>(3);
f<1>(3);
}
使用gcc 9.3-std=c++2a -Wall -Werror
你会得到一个错误(警告被视为错误):
<source>: In instantiation of 'int f(int) [with unsigned int I = 1]':
<source>:14:11: required from here
<source>:4:10: error: variable 'task' set but not used [-Werror=unused-but-set-variable]
4 | auto task = [&]() { ++x; };
| ^~~~
cc1plus: all warnings being treated as errors
这很糟糕,因为代码完全没问题,它可以被认为是触发警告的错误。显然这已在 gcc >= 10.1 中修复。
有人可能会争辩说可以/应该将声明task
移到if constexpr
分支中,但随后认为这也使 gcc 发出警告:
template <unsigned int I>
int f(int x)
{
auto task = [&]() { ++x; };
if constexpr (I == 0) {
task();
} else if constexpr (I == 1) {
task();
}
return x;
}
int main()
{
f<0>(3);
f<1>(3);
f<2>(3);
}
推荐阅读
- java - 如果配置中的类在同一个包中,为什么我必须在新配置中包含 main 的输出?
- java - groupingBy 对象列表而不是地图
- puppeteer - Puppeteer:如何在 puppeteer 中为按钮编写 XPath
- javascript - reverseArray() codeademy 使用 unshift()
- java - 无法在 Windows 10 上的 hadoop 中启动名称节点和数据节点
- coq - 错误:无法将此数字解释为 nat 类型的值
- javascript - 我们如何在缩放时减少数据图中气泡的圆半径
- django - 在 django (DRF) 中标记任何模型实例
- r - 如何在给定范围的广义线性地理空间模型中指定协变量的值?
- python-3.x - 将二进制文件转换为 0 和 1 的字符串