Why is conversion from string constant to 'char*' valid in C but invalid in C++
The C++11 Standard (ISO/IEC 14882:2011) says in § C.1.1
:
char* p = "abc"; // valid in C, invalid in C++
For the C++ it's OK as a pointer to a String Literal is harmful since any attempt to modify it leads to a crash. But why is it valid in C?
The C++11 says also:
char* p = (char*)"abc"; // OK: cast added
Which means that if a cast is added to the first statement it becomes valid.
Why does the casting makes the second statement valid in C++ and how is it different from the first one? Isn't it still harmful? If it's the case, why did the standard said that it's OK?
Up through C++03, your first example was valid, but used a deprecated implicit conversion--a string literal should be treated as being of type char const *
, since you can't modify its contents (without causing undefined behavior).
As of C++11, the implicit conversion that had been deprecated was officially removed, so code that depends on it (like your first example) should no longer compile.
You've noted one way to allow the code to compile: although the implicit conversion has been removed, an explicit conversion still works, so you can add a cast. I would not, however, consider this "fixing" the code.
Truly fixing the code requires changing the type of the pointer to the correct type:
char const *p = "abc"; // valid and safe in either C or C++.
As to why it was allowed in C++ (and still is in C): simply because there's a lot of existing code that depends on that implicit conversion, and breaking that code (at least without some official warning) apparently seemed to the standard committees like a bad idea.
It's valid in C for historical reasons. C traditionally specified that the type of a string literal was char *
rather than const char *
, although it qualified it by saying that you're not actually allowed to modify it.
When you use a cast, you're essentially telling the compiler that you know better than the default type matching rules, and it makes the assignment OK.
You can also use strdup:
char* p = strdup("abc");
or
char p[] = "abc";
as pointed here