22

Doesn't const char *s means that "s is a pointer which is pointing towards a constant char " then why it is giving me this warning? I am not trying to change values.

In first function warning is return discards 'const' qualifiers from pointer target type.

and in second warning is assignment discards 'const' qualifiers from pointer target type.

I was trying to make library functions which are defined in string.h, and also tell me how to correct it.

char *my_strchr( const char *s, int c )
{
    for(;*s!='\0';s++)
       if(*s==c)
          return s; // warning

    return 0;
}



char *my_strpbrk( const char *s1, const char *s2 )
{
    char *s2ptr;

    for(;*s1!='\0';s1++)
        for(s2ptr=s2;*s2ptr!='\0';s2ptr++) //warning
           if(*s1==*s2ptr)
               return s2ptr;

    return 0;
}
fluter
  • 13,238
  • 8
  • 62
  • 100
Ummair
  • 223
  • 1
  • 2
  • 4
  • 1
    Your `return` statement is converting `const char *` to `char *`, i.e., it's implicitly changing the type by discarding the `const` restriction. You can fix it by changing the function return type to `const char *` (or `char const *`), or removing `const` from the argument type, or you can circumvent the type system by inserting an explicit cast, i.e. `return (char *)s;` – Tom Karzes May 11 '16 at 11:30
  • Sidenote: Return value of `strpbrk` should be pointer from string `s1`, not `s2`. – user694733 May 11 '16 at 11:33
  • 1
    "const char *s means that "s is a pointer which is pointing towards a constant char " --> No. `s` points to `char` that should not be modified. The data `s` points to may or may not be constant, but this function shall not attempt to change it. Look. but don't touch. – chux - Reinstate Monica May 11 '16 at 11:35
  • @Ummair ..If any of the answers below has solved your problem, do mark any one as accepted. Read more about this here: [stackoverflow.com/help/accepted-answer](https://stackoverflow.com/help/accepted-answer) – Liju Thomas May 12 '16 at 05:23

3 Answers3

28

Doesn't const char *s means that "s is a pointer which is pointing towards a constant char"

Indeed it does. You get the warning because you are trying to convert this into a pointer pointing to a (non-constant) char. There is a rule in C saying that it is always ok to convert from pointer-to-type into pointer-to-const-type, but not the other way around.

It doesn't matter if your code tries to change the values or not. Just by using char* you tell the compiler that you want a pointer which is allowed to change values.

Most of the C standard library functions do not always make sense when it comes to "const correctness". There is for example no way to cleanly implement strchr. You will have to return (char*)s and cast away the const, which is very bad programming practice. This is the fault of the person who specified the strchr function: it is flawed by design.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 6
    Generally, there was not much thought put into the design of the C standard library. They just took a bunch of commonly used 1970s Unix functions of diverse quality and decided "these are standard". So please don't go look at the C standard lib for advise how to write functions. Some functions there are canonical (like memcpy), while some are complete nonsense and blatantly dangerous to use (gets, printf/scanf family, strncpy etc). – Lundin May 11 '16 at 11:30
  • 2
    Yeah, some of them are seriously bad (and inconsistent), like `gets()`. – Tom Karzes May 11 '16 at 11:36
  • 2
    It has only take 22 years to get rid of `gets()` (C89-C11). – chux - Reinstate Monica May 11 '16 at 11:41
  • You're using constant in place of const, those are different concepts. – 2501 May 11 '16 at 13:05
  • @2501 Yes, but that is a pointless detail in this context, this is an attempt to pedagogically try to explain basics to beginners. If you already know about the various C rules for conversions between pointer to type and pointer to qualified type, which I suspect you do, there is actually no need for you to read this answer in the first place; you'll learn nothing new from it. – Lundin May 11 '16 at 13:20
  • 1
    But beginners don't, so they will be confused when they later learn const != constant, which you taught them that it is the same. – 2501 May 11 '16 at 13:34
  • 2
    When used as a formal parameter (in a function parameter list), it means "a pointer to a char that the function promises not to change" regardless of whether it is actually a constant. – Jeff Learman Nov 07 '18 at 20:53
8

For first warning: return discards 'const' qualifiers from pointer target type

C does not have an implicit conversion from const-qualified pointer types to non-const-qualified ones, so to overcome the warning you need to add it explicitly.

Replace return s; with return (char *)s;

For second warning: assignment discards 'const' qualifiers from pointer target type

  • 's2ptr' is of type char * and 's2' is of type const char *
  • You are not allowed to assign a const char* value to a char * pointer.

And regarding how to fix this warning... It depends on what you are trying to do. Either you can make char *s2ptr as const char * s2ptr or remove the const from s2.

So if you wish to convert char *s2ptr to const char *s2ptr, do remember to explicitly cast s2ptr to (char *)s2ptr while returning it in the my_strpbrk() function.

Liju Thomas
  • 1,054
  • 5
  • 18
  • 25
-2

For the first case, your return type is a char You are trying to pass a const char as the return.

For the second case, the problem is in s2ptr=s2. s2ptr is a char and s2 is a const char.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
  • In first case my return type is `char *` I think it returns an address which POINTS to a character. In second `s2ptr` and `s2` are both pointers I am just giving the address which is in `s2` to `s2ptr`, isn't that allowed? If not how to correct it. – Ummair May 11 '16 at 11:27