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 strnlen_s
.
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 memchr
or strlen
.
EDIT
In case you must implement strnlen
yourself for some reason, then this is what I'd recommend:
#include <string.h>
size_t strnlength (const char* s, size_t n)
{
const char* found = memchr(s, '\0', n);
return found ? (size_t)(found-s) : n;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With