Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why strrchr() returns `char*` instead of `const char*`?

The function char* strrchr(const char *str, int ch) returns a pointer (char*) within str (const char *) where the last occurrence of ch is located.

So we can write the following code without any cast:

#include <string.h>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";
    char *ptr = strrchr (CONSTSTR, '/');
    *ptr++ = 'B';
    *ptr++ = 'A';
    *ptr++ = 'D';
}

What is the advantage to return char* instead of const char* ?

EDIT:
As a Shafik Yaghmour pointed out, there are very good answers to How does strchr implementation work?

As my code is in C++, I will use <cstring> instead of <string.h>. Thanks for your answers ;-)

However, the Mike Seymour's answer fits best the question. I have even added a more detailed answer below to clearly say as strrchr() is a C function (overload not permitted), the declaration fits both const and non-const strings. Because strrchr() can be called with a non-const string, the returned string should also be non-const.

like image 929
oHo Avatar asked May 31 '13 15:05

oHo


2 Answers

You're looking at the legacy function from the C standard library (<string.h>). The C++ library (<cstring>) introduces appropriate const and non-const overloads, so you should use that wherever possible.

like image 156
Oliver Charlesworth Avatar answered Sep 17 '22 14:09

Oliver Charlesworth


In C, the function must either be like this, or force the user to use dodgy casts in many situations:

  • If it took a non-const pointer, you couldn't search a const string;
  • If it returned a const pointer, you couldn't use it to modify a non-const string.

In C++, you should include <cstring> rather than the deprecated C-only header. That will give you two const-correct overloads, which couldn't be done in C:

const char* strchr(const char* s, int c);
      char* strchr(      char* s, int c);
like image 45
Mike Seymour Avatar answered Sep 16 '22 14:09

Mike Seymour