作者:百脑汇_惠州店_909 | 来源:互联网 | 2022-12-04 13:10
这段代码:
void foo(int);
int main() {
const int i = 0;
auto l = [i](){foo(i);};
}
(godbolt)
在通过clang编译时会发出编译器错误
-std=c++17 -Werror -Wunused-lambda-capture
错误消息是error: lambda capture 'i' is not required to be captured for this use
.
错误是正确的:i
可以在这里隐式捕获,明确捕获它是没有必要的.但是,a)警告命名不佳,因为i
使用了但是警告是未使用的 lambda捕获,b)我不希望这是一个错误.我希望错误的实际未使用的lambda捕获,但不是错误的已使用显式捕获的变量,可能已被隐式捕获.
是否有铿锵设置这样做?或者我是否必须使用pragma诊断推/弹来压制错误?
1> Shafik Yaghm..:
我觉得你不幸在这里运气不好.如果我们检查实现此功能的评论[Sema]为未使用的lambda捕获添加警告,我们可以看到有关如何使警告静音的讨论被广泛讨论.包括沉默未使用警告的规范铿锵方法,这种方法被转换为无效:
我认为不应该在这里使用预期警告,因为你在lambda中有(void)fname(如果我在本地测试它,我不会收到此警告).
哪个工作看到了它,但对这种情况感到愚蠢.
使用,-Wno-unused-lambda-capture
但这不是一个有利的选择:
我认为如果你将"-Wno-unused-lambda-capture"添加到CXX /目录中由此补丁修改的所有测试的选项中,补丁将更整洁.这将避免冗余(void)使用并确保(void)使用不会干扰原始意图,其中事物可能仅在捕获列表中使用.
从捕获中删除变量,因为它没有使用odr,但正如指出这暴露了实现差异,因为MSVC不进行此优化:
如果我从捕获列表中删除kDelta,它将在没有任何警告的情况下编译:
#include
int main(void) {
const int kDelta = 10000001;
auto g = [](int i)
{
printf("%d\n", i % kDelta);
};
g(2);
}
但是,然后Microsoft C++编译器将引发错误:
error C3493: 'kDelta' cannot be implicitly captured because no default capture mode has been specified
我们也可以看到这个案例,并且确实i
从捕获中删除确实为clang和gcc修复了它,但对于MSVC却没有.
适用于所有实现的另一个解决方案是明确捕获,[i=i]
但听起来这也不是一个理想的解决方案(请参见实时).
如果我们可以在这里应用[[maybe_unused]]会很好,但我们不能.