strstr
is a C99-conforming function, the type signature of which is the following:
char *strstr(const char *haystack, const char *needle);
Is it possible to implement this function without casting away a const
somewhere?
For reference, here is Apple's implementation, and here is GNU's implementation. Both cast away the const
at the end.
You can't implement strstr()
without violating const
correctness somehow. A cast is the most straightforward way to do that. You can probably hide the violation somehow (for example you could use memcpy()
to copy the pointer value), but there's no point in doing so.
The problem is that strstr()
takes a const char*
that points to a string, and returns a non-const
char*
that points into the same string.
For example, this program:
#include <stdio.h>
#include <string.h>
int main(void) {
const char s[] = "hello";
char *result = strstr(s, "hello");
*result = 'H';
puts(result);
}
modifies (or at least attempts to modify) a const
-qualified object, without using a pointer cast or any other obviously unsafe construct.
Back in 1989, the ANSI C committee could have avoided this problem by defining two different functions, say:
const char *strcstr(const char *haystack, const char *needle);
char *strstr ( char *haystack, const char *needle);
one that returns a pointer to a const char
given a const
arguments, and another that returns pointer to a modifiable char
given a modifiable argument. (C++, which inherits the C standard library, does this by overloading.)
strstr()
is one of several standard string functions that have this problem.
As Jonathan Leffler points out in a comment, C23 requires strstr()
and similar functions to be generic, so for example strstr()
returns a char*
if its first argument is char*
, or const char*
if its first argument is const char*
. The generic functions are memchr
, strchr
, strpbrk
, strrchr
, and strstr
.