60

I have a program which declares an array of strings like this:

char *colors[4] = {"red", "orange", "yellow", "blue"};

But I get the above compiler warning. It compiles but I'd rather use the non-deprecated way(if there is one). I've tried to find out what it means, but I can't seem to figure it out. I've heard using 'const' before 'char' works, but it would be helpful if someone could explain what the error means. Thanks.

rstackhouse
  • 2,238
  • 24
  • 28
Matt
  • 715
  • 1
  • 5
  • 6

3 Answers3

81

The strings that you enter: "red", "organge" etc are "literal", because they are defined inside the program code itself (they are not read directly from disk, user input /stdin etc.).

This means that if at any point you try to write to your colors you will be directly accessing your original input and thus editing it. This would cause some undesired run-time errors.

Declaring it as a const will make sure that you will never try to write to this pointer and such a run-time error can be avoided.

const char *colors[4] = {"red", "orange", "yellow", "blue"};

If you ever feel like editing these values at runtime, then you should copy the strings first.

Nate
  • 12,963
  • 4
  • 59
  • 80
d_inevitable
  • 4,381
  • 2
  • 29
  • 48
  • 5
    The type signature needed will be `char const *colors[4]`, I believe (ie an array of four const pointers). – James Aylett Mar 10 '12 at 21:01
  • 1
    @JamesAylett , no, it is `const char *colors[4]`. Array of 4 pointers to const data. – HolyBlackCat Jul 08 '14 at 12:36
  • 2
    @HolyBlackCat: Isn't it the same thing? – szx Jul 08 '14 at 12:52
  • 1
    @szx, i think, he misspelled it: `an array of four constant pointers` is a `char * const colors[4]`. `char const *colors[4]` is a strange but valid way to describe an array of 4 pointers to const data. – HolyBlackCat Jul 08 '14 at 13:17
  • 3
    'const pointer to data' is not the same as pointer to const data. One is a pointer that may not be changed but its target (the data) may be. The other is a pointer that may be changed, but its target data is const and may not be changed. Discussion at [codeguru](http://www.codeguru.com/cpp/cpp/cpp_mfc/general/article.php/c6967/Constant-Pointers-and-Pointers-to-Constants.htm). (Yeah, I know I'm a few years late but this is a frequent point of confusion). – JRobert Mar 26 '16 at 15:26
11
"red", "orange", "yellow", "blue"

these are constant string. Creating a non-const pointer to a constant string is wrong, hence the warning. At the moment you are getting a warning, but it should be an error since it is deprecated in c++03, and forbiden in c++11.

BЈовић
  • 62,405
  • 41
  • 173
  • 273
6

These answers are all correct.

Note that if you have a function requiring an array of characters as an argument and you pass this argument like this:

foo ("bar");

the same warning will be shown. In this case, you can either :

1) Change it like this, as explained in the first answer:

void foo (char[] str) { printf(str); }

const char param[] = "bar";
foo (param);

2) Consider using a C++ standard string, like so:

void foo (std::string theParam) { std::cout << theParam; }

foo ("bar");

IMHO, as long as no real performance issue is concerned and you are not working with C libraries, or if you are building a C++ library for others to use, you should rather work with C++ immutable strings and their feature set.

If Unicode is a requirement, the support in C++ is "terrible" as explained here. This question gives you some clues (mainly: use IBM ICU library). If you already have Qt in your project, QString will also do the trick, and so will Gettext.

Community
  • 1
  • 1
tiktak
  • 1,214
  • 8
  • 15
  • 1
    The function declaration `void foo (char[] str) { printf(str); }` is missing the const, it should be `void foo (const char[] str) { printf(str); }` . The former will throw a `candidate function not viable: 1st argument ('const char *') would lose const qualifier` error. – Aldo Utrera Feb 05 '15 at 16:13
  • I tried both of these approaches. The compiler warned: `invalid conversion from 'const char*' to 'char*'`. – Codes with Hammer Feb 05 '20 at 21:14