Every now and then I see people writing C++ code containing heresy in the vein of the following:
char * foo = "bar";
This is no more legal C++ than
const int qux = 42; int * quux = &qux;
It is not undefined, unspecified or implementation defined! It is simply illegal (and conveys false intent: char* implies modifiable string). It should simply not compile, though right now all the major compilers let you get away with such a conversion – but they may (and should) stop that at any time.
It is valid in C (C89 through C11), although assigning to a string literal is undefined behaviour there. C++, however, has deprecated this conversion since C++98.
C++03 §4.2/2 (conv.array/2)
A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to char”; a wide string literal can be converted to an rvalue of type “pointer to wchar_t”. In either case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [Note: this conversion is deprecated. See Annex D. ]
In fact, the original proposal would be old enough to buy alcohol around the world this year, USA included! In my opinion, more than enough time has passed to phase out that “feature”. The C++ Standards Committee seems to agree, as C++11 doesn’t list such conversion at all (conv.array has only one sub point) and, in Annex C, says the following:
C.1.1 Clause 2: lexical conventions [diff.lex]
char* p = “abc”; // valid in C, invalid in C++
In C++, we’re years past writing such code (I hope). If you need a modifiable string, initialize an array or use std::string:
char foo = "bar"; // ok std::string qux = "quux"; // ok
and if you don’t need to modify, for the sake of your co-workers (if not your own), don’t break const-correctness and use:
char const foo = "bar"; // ok, const array; be careful when using as a stack or non-static class member variable. char const * foo = "bar"; // ok, rebindable pointer char const * const foo = "bar"; // ok, non-rebindable pointer