C++ lambda captures should avoid expensive unnecessary copies

C++ lambdas can capture variables both by value and by reference. If a captured variable could be used as a reference to const, and the type is expensive to copy, then the variable should be captured by reference instead of by value.

In our projects we usually consider types as expensive to copy if their size is more than twice of a pointer or if they are not trivially copy-able.

This rule could have similar conditions as https://rules.sonarsource.com/cpp/RSPEC-6032

Hi @torgeir.skogen ,

The problem you describe should already be detected by https://rules.sonarsource.com/cpp/RSPEC-5495


That’s interesting because we have that rule active, but it didn’t find a case of an expensive copy.

Does it matter that the lambda is passed to a function that the scanner doesn’t know about? In this case we passed it to std::ranges::any_of, but we also have our own templated function that we pass lambdas to.

Yes, if the lambda is passed to a function that the scanner doesn’t know it will consider that there is a possibility the lambda is stored and thus will not raise an issue.
It should know about std::ranges::any_of, though. Were you not warned for it?

The pull request analysis for the relevant merge request doesn’t appear to have any issues on this location.

Also, I tried to reproduce it in SonarLint in Visual Studio, and it came up with nothing. I also tried to reproduce the example of non-compliant code from https://rules.sonarsource.com/cpp/RSPEC-5495 and it doesn’t appear to emit a code smell on that particular rule. It emits smells for other rules in the same snippet though, so the scanner is evidentially checking the code.

Thanks for pointing that out @torgeir.skogen. I created a ticket to fix that.