char *pc = "abc";
"abc" is what is called a string literal. It may not be stored in memory as you know it and probably cannot be changed. Trying to, for example
pc[1] = 'k';
will have unpredictable results, most likely crashing the program because that location cannot be written.
The compiler warning is telling you that you are assigning a pointer to a value you cannot or should not change to a pointer that will allow you to change the value. The quick fix here is to inform the compiler that you will not try to change "abc" and accept a slap-down by the compiler if you try.
const char *pc = "abc";
Writing to the memory referenced by pc
will now generate a compiler warning, but better that than the program writing into invalid memory and doing something weird.
This is a warning rather than an error because there are huge volumes of ancient code that does exactly this sort of risky constant->non constant assignment but never try to write to the non-writable location and would stop compiling if this was an error. For now compilers simply flag the problem and suggest you fix it.
This code:
char *pc = (char*)"abc";
cout<<*pc<<endl;
does not crash, or otherwise exhibit bad behaviour, because the location holding "abc" is readable.
char *pc = (char*)"abc";
cin >>*pc;
would be very bad if not immediately fatal.
On the other hand,
int *pi = 10 ;
is a bit different. It makes a pointer to an integer that is at memory location 10, and that is almost certainly wrong. While char *pc = "abc";
carries risk, attempting to use memory locations that have not been assigned to the program is bad and probably fatal. You hope it is fatal, because the alternative is a not-so fun game of "Dude, where's my data?" Pointers are not integers, regardless of what you may have been told, and this generating an error forces a programmer to at least think before doing something stupid.
There are exceptions in driver and embedded programming where direct hardware access is common, but these are specified with casts and other tricks to ensure the compiler that you know what you are doing and something accessible really does exist at the specified address. Precisely what you do here:
int *pi = (int*)10 ;
But the program crashes when you try to print it because there is nothing allocated and accessible for your program to read at address 10. As you can see this is considered an error for good reason. You can neither read nor write, so it does not get the conditional pass the compiler offers for the readable but not writable "abc".