In my current project, I am coding according to the C11 standard (building with
gcc -std=c11) and needed something like
strnlen (a "safe" version of
strlen which returns the length of a 0-terminated string, but only up to a given maximum). So I looked it up (e.g. https://en.cppreference.com/w/c/string/byte/strlen) and it seems the C11 standard mentions such a function, but with the name
Hence I went with
strnlen_s, but this turned out to be undefined when including
string.h. On the other hand,
strnlen is defined, so my current solution is to use
strnlen with a remark that the standard name seems to be
strnlen_s but that this is not defined by GCC.
The question is: am I correct to assume that
strnlen is the most portable name to use or what could I do for the code to be most portable/standard?
Note: Microsoft (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s) implements both functions with the distinction that
strnlen_s checks if the string pointer is
NULL and returns
0 in that case while
strnlen has no such check.
The question is: am I correct to assume that strnlen is the most portable name to use or what could I do for the code to be most portable/standard?
No, it isn't portable at all. It was never part of C. It is included in POSIX, which doesn't mean much.
I would imagine the reason why the function doesn't exist in the standard, probably because it's superfluous when we already have
memchr(str, '\0', max);.
strnlen_s is part of the optional bounds-checking interface in C11 annex K. This whole chapter turned out a huge fiasco and barely any compiler implements it. Microsoft has similar named functions but they are sometimes not compatible. So I would assume that all
_s functions are completely non-portable.
So use neither of these, use
In case you must implement
strnlen yourself for some reason, then this is what I'd recommend:
size_t strnlength (const char* s, size_t n)
const char* found = memchr(s, '\0', n);
return found ? (size_t)(found-s) : n;