This code:
void foo(int);
int main() {
const int i = 0;
auto l = [i](){foo(i);};
}
(godbolt)
Will issue a compiler error when compiled by clang with
-std=c++17 -Werror -Wunused-lambda-capture
The error message is error: lambda capture 'i' is not required to be captured for this use
.
The error is correct: i
could be implicitly captured here, explicitly capturing it is not necessary. However, a) the warning is poorly named, since i
is used but the warning is for unused lambda captures, and b) I would just not like this to be an error. I want to error for actually unused lambda captures, but not error for used explicitly captured variables that could have been implicitly captured.
Is there a clang setting that does this? Or do I have to squelch the error using pragma diagnostic push/pop?
I think you are unfortunately out of luck here. If we examine the review that implemented this feature [Sema] Add warning for unused lambda captures, we can see the discussion of how to silence the warning was extensively discussed. Including the canonical clang method of silencing unused warning, which is cast to void:
I think that expected-warning shouldn't be used here as you have (void)fname in the lambda (I don't get this warning if I test this locally).
Which does work see it live but feels silly for this case.
Using -Wno-unused-lambda-capture
but that is not a favorable option for you:
I think that the patch would be neater if you add "-Wno-unused-lambda-capture" to the options for all of the tests that are modified by this patch in the CXX/ directory. This would avoid redundant (void) uses and ensure that the (void) uses won't interfere with the original intent where things might be only used in the capture list.
Leaving out the variable from the capture since it is not odr-used but as it is pointed out this exposes implementation divergence since MSVC does not do this optimization:
It will compile without any warnings if I remove kDelta from the list of captures:
#include <stdio.h> int main(void) { const int kDelta = 10000001; auto g = [](int i) { printf("%d\n", i % kDelta); }; g(2); }
But then Microsoft C++ compiler will raise the error:
error C3493: 'kDelta' cannot be implicitly captured because no default capture mode has been specified
We can see this case live as well and indeed removing i
from the capture does indeed fix it for clang and gcc but not for MSVC.
The other solution that will work for all implemntation is to explicitly capture [i=i]
but it sounds like that is also not a desirable solution (see it live).
It would be nice if we could apply [[maybe_unused]] here but we can't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With