False-positive cpp:S5566 - STL algorithms are not applicable for constexpr functions on <C++20

  • What language is this for?
    C++11 thru C++17

  • Which rule?
    cpp:S5566

  • Why do you believe it’s a false-positive?
    According to std::all_of, std::any_of, std::none_of - cppreference.com, certain STL container algorithms are not marked as constexpr functions in C++ versions prior to 20.
    An exception should be applied for this rule if it’s analyzing a constexpr function on C++ versions prior to 20 (C++11 thru C++17)

  • Are you using…?
    SonarLint on VSCode

  • How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)

constexpr bool AllDigits_OK(const std::vector<char>& vect)
{
    for (const auto& vChar : vect) {
        if (vChar < '0' || vChar > '9')
            return false;
    }
    return true;
}

/* Fails to compile with the following error: arm-linux-gnueabihf-g++ 8.3.0 with flag -std=c++17
error: call to non-'constexpr' function 'bool std::all_of(_IIter, _IIter, _Predicate)
[with _IIter = __gnu_cxx::__normal_iterator<const char*, std::vector<char> >;
      _Predicate = AllDigits_KO(const std::vector<char>&)::<lambda(char)>]'

      return std::all_of(vect.begin(), vect.end(), [](const char vChar) {
             ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          return vChar >= '0' && vChar <= '9';
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      });
*/
constexpr bool AllDigits_KO(const std::vector<char>& vect)
{
    return std::all_of(vect.begin(), vect.end(), [](const char vChar) {
        return vChar >= '0' && vChar <= '9';
    });
}

Hello @zago27 and welcome to our community!

Thanks for sharing this feedback.

Out of curiosity, don’t you get any compiler errors with your code? I tried a similar setup as yours on Compiler Explorer but it rightfully complains begin is not constexpr. Compiler Explorer

I’ve raised [CPP-5463] - Jira to track the progress of this issue since it’s possible to face the same problem with std::array in C++17, for example.

Cheers

Yeah, my bad. I was using some sensitive code while writing down the snippet and I didn’t think this through while converting it to something more generic :sweat_smile:
I confirm the original code was using std::array, which has constexpr begin() and end() iterators.

EDIT: Here’s an edited snippet, just for completeness sake, Compiler Explorer