Fix #10412 FN useStlAlgorithm with iterators#4157
Fix #10412 FN useStlAlgorithm with iterators#4157danmar merged 53 commits intocppcheck-opensource:mainfrom
Conversation
| if (!Token::Match(loopVar, "%var%") || !loopVar->valueType() || loopVar->valueType()->type != ValueType::Type::ITERATOR) | ||
| continue; | ||
| const Token* initAssign = splitTok->astOperand1(); | ||
| if (!Token::simpleMatch(initAssign, "=") || !Token::Match(initAssign->astOperand1(), "%var%", loopVar->varId())) |
There was a problem hiding this comment.
We really should add an internal check for that - see https://trac.cppcheck.net/ticket/10987.
|
Sorry for going off-topic but we really need to take a strong look at this check. We currently do not apply these findings to our code and if we are not able to dogfood it we cannot expect others to use it. IIRC correctly there are various issues (these also apply to
|
Then maybe we should enable it? There are some pretty verbose and ugly loops in our code base...
I agree, especially in relation to std::transform.
Then that's a FP.
This could also be called an optimization/implementation bug. |
We should. I am not sure the reason why. Perhaps we need generic lambdas or something? I use it on my code bases and it works quite well. And I have had emails from users that found it quite useful.
It is confusing when there is transform_reduce, since older C++ versions does not provide this, and technically you can use However, overall it does improve readability, and you can fix the other issues by providing your own transform_reduce.
That maybe applicable to clang-tidy, but I dont that is the case here. Plus, I haven't seen an issue like this either. |
pfultz2
left a comment
There was a problem hiding this comment.
We should add comment about this in the releas-notes.txt.
+1
Maybe we should drop these or make them "inconclusive"?
From experience (and faint memory) the findings make sense but trying to fix some of them will drive you mad or the code is simply not the same or it just doesn't work. That could just be the ugly
Yes.
And no.
It seems there are certain restrictions for C++ algorithms which do not apply to C implementations and obviously not to self-rolled implementations. |
Probably something to report upstream if we come across it in our code. |
Whats the problem with
We dont suggest this.
We suggest That doesn't seems to be reason enough to stop suggesting |
This was a list of examples where modern code is not an improvement.
We do suggest that? I wasn't aware of that.
In the past I had a slow function which was in the red hot path which was using that function several times (we modernized it from I think if is there is a known trade-off (like security for performance) that should be documented. But in case of Or if you use an algorithm that improves readability but suddenly uses double-loops (like Similar to range-based for loop usage based on
Unlike clang-tidy there's no way to fine-tune such checks with Cppcheck - which I think is a good thing but we also need to be careful what we report. If we need to have performant code (which you always should have) and suddenly need to plaster code with suppressions you won't be happy about it. clang-tidy recently added several checks which you simply cannot enable since it fires for generic pattern which might cause problem but are actually extremely unlikely to do so and need very careful review and possibly lots of suppressions. They seem more like some very specific internal requirement built as a clang-tidy check. You should never blindly just change your code but if a finding results in a major headscratcher even for quite experienced devs it might be the best to report it. We really need to open the discussion section of the repo so tickets are not being hijacked for discussions...@danmar |
vs. doesn't seem to improve readability. |
This also seems prone to messing up the parameter order - especially in the four parameter version. The first example on https://en.cppreference.com/w/cpp/algorithm/transform is particular cringeworthy... |
We dont suggest to use
Also, I dont see how all these clang-tidy issues are relevant here at all, since we do not have these equivalent "modernize" checks.
Which is not relevant here since we never suggest
I dont find it cringeworthy. It would be better to make it more explicit its doing a transform in-place, that could improve readability. However, it still makes the intention of the code quite clear. Plus its easy to make it run in parallel. |
A |
|
Imho the stl algorithms are not that readable. It depends on the reader. => It would be more readable if the replacement was more like: |
LLVM has such helpers for many algorithms. Probably because of the readability among other things. |
|
C++20 improves things a little: |
|
But this PR is still about flagging iterators, which also make for unreadable code. |
I dont that would be more readable as it not clear that you are declaring Do you think a range-based return any_of(suffixes, [&](const std::string& p) {
return isPrefixStringCharLiteral(str, q, p);
});This doesn't seem anymore verbose than the original for loop plus it makes the intention clearer. HOFs could make it even more succinct. Such as return any_of(suffixes, partial(&isPrefixStringCharLiteral)(str, q));Or return any_of(suffixes, lazy(&isPrefixStringCharLiteral)(str, q, _1));Which is like return any_of(suffixes, std::bind(&isPrefixStringCharLiteral, str, q, _1));Since we dont have C++20 yet to use a range-based template <class C, class Predicate>
bool any_of(const C& c, const Predicate& p)
{
return std::any_of(c.begin(), c.end(), p);
}Although, the goal of this check is not just readability. Its to find bugs in code. If the intention of the loop is not |
This true, using the algorithm in this case is not anymore verbose than the original loop. |
That is much better. I guess the readability for that code is similar to the readability of the for loop to my eyes. It is annoying that the lambda stuff is needed. Those |
Sure, I guess its a matter of opinion, although I disagree. I think its fine we disable this for cppcheck code then, but I dont see that reason enough to remove it from cppcheck since it can find bugs and is highly recommended from many prominent C++ developers.
Yea, I dont see it as annoying. In fact, since I have started using stl algorithms on a regular basis especially with cppcheck scolding me about it, it has become quite natural to write it this way. Perhaps others may not be as familiar with algorithms or lambdas so would not see this as better. We have flags about which C++ version to use, and we only warn about the loops with C++14 or later. Perhaps we could have flags about certain feature users would like to avoid or are less familiar with so we could adjust the checks based on that.
Sure, another idea is to assign the lambda to a variable: auto hasStrPrefix = [&](const std::string& p) {
return isPrefixStringCharLiteral(str, q, p);
};
return any_of(suffixes, hasStrPrefix); |
I assume its easier to find places to replace If its very important to use I am sure if you see cppcheck complaining about a raw loop needing to use |
|
Any more feedback on this? |
My opinion is still the same. Looking at the code I also wonder if this might impact the performance. |
|
So I made this mergeable once more. How about it? |
No description provided.