Inspired by this question about the following code from SQLite3:
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
that is accompanied by a commit message saying this function helps with int overflows.
I’m particularly interested in this part:
const char *z2 = z;
while( *z2 ){ z2++; }
to me this loop advances z2 until z2 points onto null terminator. Then z2-z yields the string length.
Why not use strlen() for this part and rewrite like this:
return 0x3fffffff & (int)(strlen(z));
Why use loop+subtraction instead of strlen()? What can loop+subtraction do what strlen() can’t?
I suspect the real answer is that the programmer felt like it, but another potential justification/rationalisation is that the loop is inline (independent of whether
strlen30itself is), whereas on many systemsstrlenis an out-of-line function call (e.g. Linux/GCC). If the overwhelming majority of strings are empty or short (despite the “special” treatment of long ones), then that may yield a slight performance bump for the common case. That possibility alone may be enough to get a code-happy programmer key-tapping. For longer strings I would expect the librarystrlento be generally optimal (allowing for it’s lack of knowledge of the application specific length of strings).Some systems may not even benefit from this inlining as
strlenprovides it’s own, or an inline/out-of-line hybrid with a quick inline check for empty, one-char, maybe two-char strings then a call.