I've translated an [implementation of strlen in x86 assembly][1] to C and added alignment checking: ``` #include <strings.h> #include <string.h> #include <stdint.h> #define NOT_HIGH_MASK 0x080808080 #define HIGH_MASK 0x7f7f7f7f #define LOW_MASK 0x01010101 #define mul4(x) ((x) << 2) #define div8(x) ((x) >> 3) size_t strlen(const char *str) { const char *cptr = str; uint32_t i, *s; size_t ctr = 0; /* Satisfy alignment requirements */ while((uintptr_t)cptr & (sizeof(uint32_t)-1)) { if(!*cptr) return cptr - str; cptr++; } s = (uint32_t *)cptr; do { i = s[ctr]; /* Mask off high bit */ i &= HIGH_MASK; /* subtract 0x01 from each byte, giving a set high bit if it was zero */ i -= LOW_MASK; ctr++; /* Test for the set high bit and if it is found exit */ } while(!(i &= NOT_HIGH_MASK)); /* Find the first high bit set and create the corresponding byte index */ i = div8(ffs(i)); /* Remove the counter increment from the loop and multiply it by 4 to find the rest of the byte index */ ctr = mul4(ctr - 1); /* Return the combined byte index with 1 removed so it doesn't include the null terminator itself */ return i + ctr - 1; } ``` I'm looking for general critique, but I'd also like additional information in these areas: * Portability. Is this portable? Will it work on all common platforms (x86, arm, etc.) and possibly some uncommon ones? * Comments. The comments I've put here seem to already document the code well enough, but is there any additional information I could add? * Hidden Bugs. This definitely works (and has a noticeable improvement in speed), but are there any hidden bugs relating to alignment requirements or otherwise (such as extended ASCII)? For context, this is part of a standard C/POSIX library implementation. I might note that I'm relying on my header to use the builtin version of `ffs`. This may be an issue on non-GNU compilers. [1]: https://codereview.stackexchange.com/questions/210689/strlen-and-strcmp-implementation-in-x86-fasm-assembly/213558#213558