Your compiler may decide to file a complaint about comparing signed with unsigned - GCC or Clang, if provoked * but otherwise it "works." On two-component machines (most machines today) (size_t)-1 same as SIZE_MAX - indeed, as discussed in extenso in the comments, this is the same for machines with one addition or a symbolic value due to the wording in clause 6.3. 3.3 standards C99 and C11).
Using (size_t)-1 to indicate "not found" means that you cannot distinguish between the last record in the maximum possible array and "not found", but this is rarely an actual problem.
So, is this just a one-edge case in which I might have a problem?
The array must be a char array, however, in order to be large enough to cause problems - and although you can have 4 GiB memories with a 32-bit machine, it is pretty implausible to have all the memory in an array of characters (and this is much less likely that problem with 64-bit machines, most of them do not work up to 16 exbibytes of memory). Thus, this is not a practical edge case.
On POSIX, there is a type ssize_t , a signed type of the same size size_t . You can use this instead of size_t . However, this causes the same longing that (size_t)-1 causes, in my experience. In addition, on a 32-bit machine, you may have a 3 gigabyte memory block processed as a char array, but with ssize_t you could not use more than two GiB as the return type - d you need to use SSIZE_MIN (if it exists, I don’t sure he does) instead of -1 as the signal value.
* GCC or Clang needs to be provoked quite difficult. Just using -Wall not enough; A warning is required by -Wextra (or the specific -Wsign-compare option). Since I usually compile with -Wextra , I know about this problem; not everyone is just as vigilant.
Comparison of signed and unsigned values is completely determined by the standard, but can lead to counter-intuitive results (since small negative numbers look very large when converted to unsigned values), so compilers complain if they require it.