Remove excessive and wrong use of std::forward#1401
Conversation
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
Signed-off-by: Tony Xiang <[email protected]>
|
mgovers
left a comment
There was a problem hiding this comment.
i would argue against globally disabling the check of both clang-tidy and sonar cloud. i get that there are multiple separate reasons why one would use it, and i get that it clutters the codebase, but i generally am of the opinion that the people working for sonar and clang are probably more aware of the details etc. than we are. also, even within the maintainer team, not everyone is as aware as you are as to when which use case is used. IMO, we should better be safe than sorry.
Replying to your general comments @mgovers. The actual legitimate use of template <class... Args>
decltype(auto) some_func(Args&&... args) {
return some_other_func(std::forward<Args>(args)...);
}Even for this case, missing So the proposal to disable rules globally is based on three major facts:
And no, for this particular case, sonar and clang-tidy is wrong in big way. They simply cannot distinguish difference use-cases of universal reference in a deterministic way. |
|
@mgovers @TonyXiang8787 Can we do a knowledge sharing for everyone before we merge this? I can prepare it if so. It's good to be aligned first and make sure we all understand the subtleties well. |
The intention is indeed to discuss and agree with the maintainers, then merge (possibly with adjustments). |




Background
This PR fixes a code quality problem. In the code base,
std::forwardis excessively used. Most of the usage is not justified, but merely to satisfy theclang-tidyandsonarrules. This PR removes those usage and adjusts the rules.Functor object as function argument should be passed by value
One misuse of
std::forwardis wrongly declaring functor object in function argument as universal reference. See below:The CPP guideline is clear: Function objects should be cheap to copy (and therefore passed by value).
Defining functor argument as reference is not correct. The PR changes this back to pass by value. See below. Note the declaring universal reference for
argsand usestd::forwardonargsis correct, which is actually the only correct usage ofstd::forwardin PGM code base.Universal reference is used as capture temporary proxy object, it should not be forwarded
The universal reference (or the confusing name forwading reference) is not only meant to be used when you want to do perfect forwarding. It has another major use-case: capturing temporary proxy object. The proxy object can be:
eigenexpression templatestd::ranges::viewswhich is constructed on the flySelf&&is declared as universal reference to be able to capture a temporary created object.In all this cases, nothing will need to be forwarded. Thus usage of
std::forwarddoes not make sense. The clang-tidy and sonar unfortunatley cannot detect this use-case, and raise false warning.We should just remove the
std::forwardhere.When to use std::forward? Why clang-tidy complains so much?
std::forwardis only justified if we expect that the follow-up function has potentially a rvalue reference overload which could consume the object. This is relatively rare in PGM. On the other hand, the use-case of universal reference to capture temporary proxy object is huge in PGM.Unfortunately, both of them do not have good mechanism to detect the other legitimate use-case of universal reference. This results in many false warning from clang-tidy and sonar. This PR proposes to silence this rule for both clang-tidy and sonar globally. Silencing it locally would create too much
//NOLINTcomment which hams readability and again just trying to please clang-tidy.