Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come C standard library function `strchr` returns pointer to non-const, when given `const char *` as first argument?

Compilation of given code sample with gcc/g++ succeeds. There is no error for strchr call, which obviously assignes const char * to char *.

I've found strchr is declared as char * strchr(const char *, int) on two different sources pubs.opengroup.org and cplusplus.com

If strchr is implemented as to cast away constness, then why's that so?

If goal was to provide function which works both on char * and const char * strings - it could have been implemented using two different function names.

Can you give more thorough explanation on this.

#include <string.h>

int main () {
    const char *str = "Sample string";
    char * ptr;

    //ptr = str;            //  Error: discards const qualifier - both on gcc and g++
    pch = strchr(str,'S');  //  Succeeds in assigning <const char *> to <char *>

    *pch = '4';             //  Runtime error: segmentation fault

    return 0;
}

Tried it on Win7 using MSYS2/mingw-w64 gcc_v5.3.0 and TDM-gcc32 v5.1.0 .

like image 491
MKPS Avatar asked Jan 17 '16 18:01

MKPS


People also ask

What does Strchr return in c?

The strchr() function returns a pointer to the first occurrence of c that is converted to a character in string. The function returns NULL if the specified character is not found.

Why does Strchr take an int?

char *strchr(const char *s, int c); because int is what the above legacy implementation expects to physically receive as c . Declaring it with a char parameter would be incorrect. For this reason, you will never see "traditional" standard library functions expecting parameters of type char , short or float .

Why Strchr is used in c?

An strchr() function is used to find the first occurrence of a specified character within the original string. In other words, an strchr() function checks whether the original string contains defined characters.

What does Strchr mean in C++?

In C++, strchr() is a predefined function used for finding the occurrence of a character in a string. It is present in cstring header file. Syntax: // Returns pointer to the first occurrence.


1 Answers

When you call strchr with a char* you want a char* back, so that you don't need to do a cast on the result. C doesn't support function overloading, so the same strchr function is used for searching in a char* and in a const char*. It returns a non-const pointer in all cases. If you call it with a const char* it is basically casting away the const so it is the callers responsibility to use it safely (e.g. by assigning the result to a const char* immediately, to avoid any unsafe use of the returned pointer).

If goal was to provide function which works both on char * and const char * strings - it could have been implemented using two different function names.

Yes, it could have been, but it isn't done like that. The original version of C didn't support const at all, so it was always the programmer's responsibility to avoid trying to modify string literals. If different function names were used then it would have broken existing code that used strchr safely. It would have slowed the adoption of the new const keyword if traditional C code like this suddenly stopped compiling:

char arr[] = "foo bar";
*strchr(arr, 'r') = 'z';

The "spirit of C" is that it doesn't try to stop you doing unsafe things, it's your job to write correct code.

In C++ strchr is overloaded to preserve constness:

char* strchr(char*, int);
const char* strchr(const char*, int);

This means it automatically does the right thing, and it's much harder to accidentally write unsafe code with strchr.

like image 198
Jonathan Wakely Avatar answered Oct 30 '22 06:10

Jonathan Wakely