I tried to write my own implementation of the strchr() method.
It now looks like this:
char *mystrchr(const char *s, int c) {
while (*s != (char) c) {
if (!*s++) {
return NULL;
}
}
return (char *)s;
}
The last line originally was
return s;
But this didn’t work because s is const. I found out that there needs to be this cast (char *), but I honestly don’t know what I am doing there 🙁 Can someone explain?
I believe this is actually a flaw in the C Standard’s definition of the
strchr()function. (I’ll be happy to be proven wrong.) (Replying to the comments, it’s arguable whether it’s really a flaw; IMHO it’s still poor design. It can be used safely, but it’s too easy to use it unsafely.)Here’s what the C standard says:
Which means that this program:
even though it carefully defines the pointer to the string literal as a pointer to
constchar, has undefined behavior, since it modifies the string literal. gcc, at least, doesn’t warn about this, and the program dies with a segmentation fault.The problem is that
strchr()takes aconst char*argument, which means it promises not to modify the data thatspoints to — but it returns a plainchar*, which permits the caller to modify the same data.Here’s another example;
it doesn’t have undefined behavior, butit quietly modifies aconstqualified object without any casts (which, on further thought, I believe has undefined behavior):Which means, I think, (to answer your question) that a C implementation of
strchr()has to cast its result to convert it fromconst char*tochar*, or do something equivalent.This is why C++, in one of the few changes it makes to the C standard library, replaces
strchr()with two overloaded functions of the same name:Of course C can’t do this.
An alternative would have been to replace
strchrby two functions, one taking aconst char*and returning aconst char*, and another taking achar*and returning achar*. Unlike in C++, the two functions would have to have different names, perhapsstrchrandstrcchr.(Historically,
constwas added to C afterstrchr()had already been defined. This was probably the only way to keepstrchr()without breaking existing code.)strchr()is not the only C standard library function that has this problem. The list of affected function (I think this list is complete but I don’t guarantee it) is:(all declared in
<string.h>) and:(declared in
<stdlib.h>). All these functions take a pointer toconstdata that points to the initial element of an array, and return a non-constpointer to an element of that array.