2

The following code is producing a warning:

const char * mystr = "\r\nHello";
void send_str(char * str);

void main(void){
    send_str(mystr);
}
void send_str(char * str){
    // send it
}

The error is:

Warning [359] C:\main.c; 5.15 illegal conversion between pointer types
pointer to const unsigned char -> pointer to unsigned char

How can I change the code to compile without warnings? The send_str() function also needs to be able to accept non-const strings.

(I am compiling for the PIC16F77 with the Hi-Tech-C compiler)

Thanks

Jodes
  • 14,118
  • 26
  • 97
  • 156
  • 2
    A `char *` can be converted to a `const char *`, but not vice versa. So just change `send_str` to take a `const char *`. – Oliver Charlesworth Feb 20 '14 at 09:34
  • Thanks! Why can it be converted one way but not the other? – Jodes Feb 20 '14 at 09:46
  • 2
    Consider what `const` means: a "read-only" variable. It's totally fine to treat a writeable variable as if it were read-only, but not vice versa. – Oliver Charlesworth Feb 20 '14 at 09:47
  • 1
    @Jodes: Because `mystr` points to (aka: it contains the address of) _read only_ memory that contains `\r\nHello`. That memory can't be changed, so the pointer is a `const` pointer. If you pass it to a function that takes a non-const `char *`, that function should be allowed to change the string `char *arg` points to. This is not allowed with a `const char *`. A rw `char *`, passed to a function that, because of the argument being `const char *` "vows" not to change the string, is not a problem, of course – Elias Van Ootegem Feb 20 '14 at 09:50
  • 1
    read `const char *var = "string"` as `dont-touch char *var` and `char *some_str` as `touch-or-not char *some_str` a non `const` pointer can be read and written to – Elias Van Ootegem Feb 20 '14 at 09:51

2 Answers2

5

You need to add a cast, since you're passing constant data to a function that says "I might change this":

send_str((char *) mystr);  /* cast away the const */

Of course, if the function does decide to change the data that is in reality supposed to be constant (such as a string literal), you will get undefined behavior.

Perhaps I mis-understood you, though. If send_str() never needs to change its input, but might get called with data that is non-constant in the caller's context, then you should just make the argument const since that just say "I won't change this":

void send_str(const char *str);

This can safely be called with both constant and non-constant data:

char modifiable[32] = "hello";
const char *constant = "world";

send_str(modifiable);  /* no warning */
send_str(constant);    /* no warning */
unwind
  • 391,730
  • 64
  • 469
  • 606
  • It is much better practice to rewrite the send_str function to use `const`, if that is an option. – Lundin Feb 20 '14 at 09:47
  • 1
    Also, [`main()` does not necessarily return `int`](http://stackoverflow.com/questions/5296163/why-is-the-type-of-the-main-function-in-c-and-c-left-to-the-user-to-define/5296593#5296593). – Lundin Feb 20 '14 at 09:47
  • @Lundin Agreed, I edited the `const` in there, I mis-read the question's requirements. And removed the `main()` comment, thanks. – unwind Feb 20 '14 at 09:48
5

change the following lines

void send_str(char * str){
// send it
}

TO

void send_str(const char * str){
// send it
}

your compiler is saying that the const char pointer your sending is being converted to char pointer. changing its value in the function send_str may lead to undefined behaviour.(Most of the cases calling and called function wont be written by the same person , someone else may use your code and call it looking at the prototype which is not right.)

KARTHIK BHAT
  • 1,410
  • 13
  • 23