Is it bad to declare a C-style string without const? If so, why?

Solution 1:

Yes, this declaration is bad practice, because it allows many ways of accidentally provoking Undefined Behavior by writing to a string literal, including:

cool[0] = 'k';
strcpy(cool, "oops");

On the other hand, this is perfectly fine, since it allocates a non-const array of chars:

char cool[] = "cool";

Solution 2:

Yes, in C++ you should always refer to string literals with variables of type const char * or const char [N]. This is also best practice when writing new C code.

String literals are stored in read-only memory, when this is possible; their type is properly const-qualified. C, but not C++, includes a backward compatibility wart where the compiler gives them the type char [N] even though they are stored in read-only memory. This is because string literals are older than the const qualifier. const was invented in the run-up to what's now called "C89" -- the earlier "K&R" form of the language did not have it.

Some C compilers include an optional mode in which the backward compatibility wart is disabled, and char *foo = "..."; will get you the same or a similar diagnostic that it does in C++. GCC spells this mode -Wwrite-strings. I highly recommend it for new code; however, turning it on for old code is liable to require an enormous amount of scutwork for very little benefit.