strlen
returns the number of characters that precede the terminating null character. An implementation of strlen
might look like this:
size_t strlen(const char * str)
{
const char *s;
for (s = str; *s; ++s) {}
return(s - str);
}
This particular implementation dereferences s
, where s
may contain indeterminate values. It's equivalent to this:
int a;
int* p = &a;
*p;
So for example if one were to do this (which causes strlen
to give an incorrect output):
char buffer[10];
buffer[9] = '\0';
strlen(buffer);
Is it undefined behavior?
The behavior of the variant that you are showing is well defined under these circumstances.
0
.char
value can be accessed without UB, the clauses about trap representations in the standard explicitly exclude all character types from that.char
value.for
loop stops at latest at position9
, so you will not overrun your array.So no "bad" things beyond the visible may happen if you use your specific version of the function. But having a function call that produces unspecified results is certainly nothing you want to see in real code. Something like this here leads to very subtle bugs, and you should avoid it by all means.
Yes, it's undefined behaviour. From the draft C11 standard, §J.2 "Undefined behavior":
No, it's not undefined behavior. Your strlen function will stop before the end of the buffer. If your strlen function referenced buffer[10], then, yes that is undefined.
It certainly will be unexpected behavior, since most of buffer contains random data. "Undefined" is special word for people writing language standards. It means that anything could happen, including memory faults or exiting the program. By unexpected, I mean that it sure not what the programmer wanted to happen. On some runs, the result of strlen could be 3 or it could be 10.
Calling the standard function
strlen
causes undefined behaviour. DR 451 clarifies this:For a more in-depth discussion see this thread.