Skip to content

25 Beginner The Hundred

The Search That Always Succeeds

the spam filter with a 100% detection rate

#include <iostream>
#include <string>

int main() {
    std::string subject = "Meeting notes for Tuesday";

    if (subject.find("URGENT") >= 0) {
        std::cout << "spam detected: " << subject << '\n';
    } else {
        std::cout << "inbox: " << subject << '\n';
    }
}

Run it. What does it print?

Answer

spam detected: Meeting notes for Tuesday — the branch is taken for every subject, match or no match.

Why

find doesn't return a bool — it returns the position of the match as a std::size_t, and reports "not found" with the special value std::string::npos. npos is defined as size_t(-1), which on an unsigned type wraps around to the largest possible value (18,446,744,073,709,551,615 on x86-64) — about as far from "less than zero" as a number can get. Since no unsigned value is ever negative, >= 0 is true for hits and misses alike. Dropping the comparison — if (subject.find("URGENT")) — is the mirror-image trap: a match at position 0 converts to false, so the one subject that genuinely starts with "URGENT" sails through. -Wall alone is silent here, but -Wextra catches it: warning: comparison of unsigned expression in ‘>= 0’ is always true [-Wtype-limits].

The fix

Compare against the sentinel by name — or, since C++23, ask the question you meant to ask:

if (subject.find("URGENT") != std::string::npos)   // C++17: the idiomatic test
if (subject.contains("URGENT"))                    // C++23: says what it means

Takeaway: find returns a position, not a boolean — the only honest test is != npos (or contains).

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry