Link to home
Start Free TrialLog in
Avatar of william007
william007

asked on

About string

Am I right that string literal("abc") is of type const char[]?
If yes, may I know why we can modify "abc" to "cbc" using the following code? Does string class make a copy of const char[] and manipulate it?
string word="abc";
word[0]='c';
cout<<word<<endl;

Open in new window

Avatar of alb66
alb66
Flag of Italy image

SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Oops formatting error on above post...

>> Am I right that string literal("abc") is of type const char[]?
The object literal is not of type const char[] but the c-style character string used to initialize it is. The object literal is of type basic_string typedef'ed as 'typedef basic_string string;'
http://www.cplusplus.com/reference/string/string/

>> If yes, may I know why we can modify "abc" to "cbc" using the following code?
Internally std::string holds a pointer to a char * buffer and then you use the [] operator it invokes the overloaded operator on the string class and modifies the internal buffer.
http://www.cplusplus.com/reference/string/string/operator[].html
As evilrix said, the [] operator, in this case, is used only to get access to individual chars in the string. And cannot be used to set chars, because internally, the string class makes use of a private member to store the string itself, and we cannot directly get access to this member.

So one need to use something like

string& insert ( size_t pos1, const char * s, size_t n );
>> As evilrix said, the [] operator, in this case, is used only to get access to individual chars in the string. And cannot be used to set chars

I don't think that's what evilrix said. The operator[] of the STL string class can be used to modify characters in the string :

        http://www.cplusplus.com/reference/string/string/operator%5B%5D.html
>> I don't think that's what evilrix said. The operator[] of the STL string class can be used to modify characters in the string :
No, I didn't say that at all. I said quite clearly, "then you use the [] operator it invokes the overloaded operator on the string class and modifies the internal buffer."

The operator[] returns a reference to the char you are indexing so it CAN be used to modify the internal buffer.

There are actually 2 operator[] members, one const and one non-const. The const one is used when the string object is const because, clearly, if the string is const it is not mutable.

const char& operator[] ( size_t pos ) const;
char& operator[] ( size_t pos );
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of william007
william007

ASKER

Thanks..but as alb66 pointed out from the MSDN document, string literal is of type char[] instead of const char[].
But is that vary from compiler to compiler?
>> But is that vary from compiler to compiler?
A string literal is actually type char const [] but an assignment can be made to a type char[]. You cannot; however, modify a string literal.. to attempt to do so will cause a crash. try it...


int main()
{
	char a[] = "hello"; // pointer to char const []
	a[0] = 'j'; // Ok
 
	char * p = "hello"; // pointer to char const []
	p[0] = 'j';
}

Open in new window

>> A string literal is actually type char const []
The C++ Standard specifically states

"2.13.4

1. An ordinary string literal has type array of n const char and static storage duration, where n is the size of the string as defined below, and is initialized with the given characters. A string literal that begins with L, such as L"asdf", is a wide string literal. A wide string literal has type array of n const wchar_t and has static storage duration, where n is the size of the string as defined below, and is initialized with the given characters."

Note that const char [] and char const [] are semantically identical both mean an array of const char.
>> but as alb66 pointed out from the MSDN document, string literal is of type char[] instead of const char[].

That's wrong ;) It might be true for MS's implementation of the C++ language, but it's not true for the language itself.
>>>> string literal is of type char[] instead of const char[].
If you can assign a literal to a non const char pointer, the compiler obviously doesn't take the right side as a const char* or it would have an error.  If I understand evilrix' last post correctly, even a compiler which is nearly compliant to C++ standard allows the assignment of a literal to non-const char pointer and won't complain at compile time. When it crashes at run-time it isn't actually a contradiction to the MSDN which says that "the behavior is undefined".
>> If I understand evilrix' last post correctly, even a compiler which is nearly compliant to C++ standard allows the assignment of a literal to non-const char pointer and won't complain at compile time

The ability to assign a string literal to a non-const pointer has been deprecated in C++.

ISO/IEC 14882:2003(E) Annex C

Change: String literals made const

The type of a string literal is changed from array of char to array of const char. The type of a wide string literal is changed from array of wchar_t to array of const wchar_t.

Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Simple syntactic transformation, because string literals can be converted to char*; (4.2). The most common cases are handled by a new but deprecated standard conversion:

   char* p = "abc"; // valid in C, deprecated in C + +
   char* q = expr ? "abc" : "de"; // valid in C, invalid in C + +

How widely used: Programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are probably rare.
Thanks:)