Search code examples
cpointersconstantsglibc

return type for strchr() non const?


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); ?


Solution

  • 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)