Home > Software design >  Is std::equal guaranteed to short circuit?
Is std::equal guaranteed to short circuit?

Time:07-11

I would like to compare a nul-terminated string against a string literal. I hope to use std::equal and am curious if this code is well-defined according to the C standard:

#include <algorithm>

bool is_foo(const char *str) {
    const char *lit = "foo";
    return std::equal(lit, lit   4, str);
}

If std::equal is guaranteed to stop at the first mismatch, then this code seems defined to me even if str has length < 3. If there is no such guarantee then I think this may dereference past the end of str resulting in UB.

What if anything does the C spec say about this? Thanks for any help!

CodePudding user response:

My reading of the C standard indicates that this is pedantically undefined behavior based on the following remark:

Remarks: If last2 was not given in the argument list, it denotes first2 (last1 - first1) below.

This is referring to overloads of std::equal that do not supply the second sequence's ending iterator. In this case this would not be a valid pointer, hence this is pedantically undefined behavior, given the following part of the specification:

E be: pred(*i, *(first2 (i - first1))) for the overloads with no parameter proj1;

...

Returns: If last1 - first1 != last2 - first2, return false. Otherwise return true if E holds for every iterator i in the range [first1, last1) Otherwise, returns false.

I see nothing here that guarantees short circuit evaluation. The complexity does not seem to imply guaranteed short-circuit evaluation, either:

Complexity:

[ ... ]

... at most min(last1 - first1, last2 - first2) applications of ...

The "at most" part is not qualified in any way. Strictly interpreted this allows, but not requires, short-circuit evaluation.

  • Related