On Debian 9, with GCC 8.2, libc6-dev:amd64
2.27:
The man page for strchr
(and many other <string.h>
functions) has this prototype:
char *strchr(const char *s, int c);
How can it return a non-const
char *
, when its source is a const char *
?
Shouldn't the prototype be const char *strchr(const char *str, int c);
?
Shouldn't the prototype be
const char *strchr(const char *str, int c);
No due to backward compatibility and wider applicability.
In C's early days const
did not exist and strchr()
was effectivley like
char *strchr(char *str, int c);
With the addition of const
, changing the str
argument from char *
to const char *
did not break existing code yet nicely allowed new code to pass char *
or const char *
to strchr()
. That const
in the signature also indicated that strchr(const char *str, ...)
did not alter the data pointed to by str
.
Returning const char *
from strchr()
would have broken existing code. Further when strchr()
is called with a char *
, returning a char *
is fine. With function overloading, as in C++, both functions exists.
char *strchr(char *str, int c);
const char *strchr(const char *str, int c);
The same issue applies to many other functions: strto...(), bsearch(), memchr(), strpbrk(), strrchr(), strstr(), ...
It is a consideration for new code, should you developed a function that returns a pointer derived from a supplied pointer: return const
or not, or form 2 functions (perhaps steered by _Generic
)?
const_or_not char *foo(const char *s)