MMM
MMM

Reputation: 69

Difference between const char[] and char[]

Marray(char MyString [])
Marray(const char MyString [])

What is the difference between these two lines? I was reading about difference between const char* and char*. Is it the same with char[] and const char []? I am confused, since in both cases, when I overload operator [], change of the string literal is possible. const char* is a mutable pointer to an immutable character/string. -- So I was expecting the same with const char [], but the string is mutable...

more code:

constructor:

Marray::Marray(const char MyString []){
    length = 0;

    while(MyString[length]!=NULL){  
        length ++;
    }

    text= new char [length+1];

    int i;
    for (i=0; i<length; i++)
        *(text+i)=MyString[i];
    text[length]=NULL;
}

char & Marray::operator[] (int i) const { return text[i];}

int main () {

    Marray n("String");

    n[3]='d';

    n.getMarray();

    system("pause");
    return 0;
}

And this is what I got after running:

Strdng

So, the string is changed, even though there is const char[].

Upvotes: 2

Views: 678

Answers (3)

anatolyg
anatolyg

Reputation: 28300

The constructor with the const only promises not to change the parameter it receives. That is, it promises that the following code will write String:

char mystring[] = "String";
Marray n(mystring);
std::cout << mystring;

However, your class wants to provide the service of changing its contents even when passed an immutable string - so it must copy the string into another storage, which is mutable.

If you want to have the effect you described, you can make an immutable object:

char mystring[] = "String";
const Marray n(mystring);
n[3]='d'; // compilation error

Update: As noted by hvd in a comment, to make the compiler issue an error, you will need to fix the declaration of operator[]:

char& Marray::operator[] (int i) { return text[i];} // non-const version
const char& Marray::operator[] (int i) const { return text[i];} // const version

or (better)

char& Marray::operator[] (int i) { return text[i];} // non-const version
char Marray::operator[] (int i) const { return text[i];} // const version

(see e.g. this answer to find out why you need 2 versions of the same operator).

Upvotes: 1

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154025

First off, according to 8.5.3 [dcl.fct] paragaph 5 the function argument types are adjusted to be pointer types:

... After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively.

That is, the question becomes "What's the difference between passing T* and T const*?" and the obvious answer is, the constness of the objects pointed to.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726987

I was reading about difference between const char* and char*. Is it the same with char[] and const char []?

For most practical purposes, the answer is "yes". Although generally char const* and char const[] are two different types, one can become the other based on the context. In this specific context (a declaration of a function parameter) they do mean the same thing.

So I was expecting the same with const char [], but the string is mutable

No, the C string passed into the function remains constant due to the const qualifier (demo). An attempt to modify const char MyString[] inside Array would produce a compile-time error:

error: assignment of read-only location ‘* s’

Upvotes: 3

Related Questions