3
votes

I have some code:

const string MY_STRINGS[3] = { "A", "B", "C" };

and when I try to do this:

int main() {
  MY_STRINGS[1] = MY_STRINGS[2];
}

I get the following error:

Passing 'const std::string' as 'this' argument of 'std::basic_string... & std::basic_string::operator= ...' discards qualifiers.

Sure. Makes sense. I can't assign to a const string.

But when I do the following:

int main() {
  const string SOME_STRINGS[3] = MY_STRINGS;
  MY_STRINGS[1] = MY_STRINGS[2];
}

this compiles and works. What has changed, and why does it now compile?

3
This fails to compile on VS2010 (had to change initialisation of SOME_STRINGS to SOME_STRINGS[3] = { MY_STRINGS[0], ... };. What compiler are you using? Can you post a single block of code that causes this?hmjd
@hmjd: I've confirmed this behaviour with GCC 4.3.4: ideone.com/qWNjy.Oliver Charlesworth
@hmjd that is indeed what I meant (though I have SOME_STRINGS[3]?). And yes, I'm compiling on GCC 4.2.1.Alex Churchill
@alexc, no I didn't change SOME_STRINGS at all: just stating that I had to use initializer braces for VS2010 to compile it. Anyway, it is not really relevant to your actual question (I was concerned it was not the actual code posted but it has been reproduced).hmjd

3 Answers

0
votes

First, avoid naming your identifiers with ALL_CAPS.

Second, I really do not believe your second code snippet would actually compile.

Try this in your compiler and if this compiles as well, your compiler is broken:

int main()
{
   int foo[3] = {1, 2, 3};
   int bar[3] = foo; // Should fail to compile here.
}
0
votes

I believe GCC copies the array. Thus ensuring the const array is immutable and the variable array mutable.

#include <string>
#include <iostream>

using namespace std;

int main() {
    string varStrs[] = {"unchanged", "changed"};
    const string constStrs[2] = varStrs;

    varStrs[0] = varStrs[1];
    //constStrs[0] = constStrs[1]; // <-- will not compile

    cout << "const str: " << constStrs[0] << endl;
    cout << "var str: " << varStrs[0] << endl;

    return 0;
}

I tested this on GCC version 4.1.2

0
votes

Compiler bug.

First, const string SOME_STRINGS[3] = MY_STRINGS; is not legal C++. It must be a GCC extension or something to allow arrays to be copy-initialised.

Second, this extension seems to break detection of even the most basic type-safety violation (assiging to a const). This is worrying.