Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::search_n be called with a count of 0?

Can std::search_n be called "safely" with a count of 0? Specifically, is code like the following valid?

#include <algorithm>
#include <cstdio>

int main(int argc, char *argv[]) {
    const int test[7] = {1, 2, 3, 4, 5, 6, 7};
    const int *const location = std::search_n(test, test + 7, 0, 8);
    if (location == test) {
        std::puts("Found it at the beginning!");
    }
}

I would expect this code to reach the std::puts statement, and most descriptions of std::search_n seem to imply that it will. However, most sample implementations that I'm finding won't. What sayeth the standard?

like image 577
Joshua Green Avatar asked Oct 03 '14 21:10

Joshua Green


1 Answers

The specification of std::search_n is (§25.2.13 [alg.search]/p4-7):

template<class ForwardIterator, class Size, class T,
class BinaryPredicate>
ForwardIterator
search_n(ForwardIterator first, ForwardIterator last, Size count,
const T& value, BinaryPredicate pred);

4 Requires: The type Size shall be convertible to integral type (4.7, 12.3).

5 Effects: Finds a subsequence of equal values in a sequence.

6 Returns: The first iterator i in the range [first,last-count) such that for every non-negative integer n less than count the following corresponding conditions hold: *(i + n) == value, pred(*(i + n),value) != false. Returns last if no such iterator is found.

7 Complexity: At most last - first applications of the corresponding predicate.

When count <= 0, there is no non-negative integer n less than count, so the condition "for every* non-negative integer n less than count ..." is always true**, and so it should return the first iterator in range - which is first. Note that the spec implies that you are not allowed to pass a negative count if last-count isn't well-defined, but nothing in the spec prevents count from having a value of zero.

All standard library implementations I tested (libstdc++, libc++, MSVC) print the message.


*This used to be "for any...". LWG issue 2150 changed the wording here to clarify the intended meaning.

**The statement "for every x in S, p" is vacuously true if S is an empty set.

like image 162
T.C. Avatar answered Oct 02 '22 23:10

T.C.