2

In case 1 the output is blank when I initialize a string like this:

 #include <iostream>
 #include<string>

 using namespace std;
 //CODE 1
 int main()
 {
    string s="hello" + 'c';
    cout<<s<<endl;
    return 0;
 }

but when I write it this way it works fine:

 #include <iostream>
 #include<string>

 using namespace std;
 //CODE 2
 int main()
 {
     string s="hello";
     char k='c';
     s+=k;
     cout<<s<<endl;
     return 0;
 }

Now I am confused as in another question asked on stack overflow it says that there is no difference between string and std::string when namespace std is used, those answers go by saying that -> There is no functionality difference between string and std::string because they're the same type std::string vs string in c++ whereas the answers provided for this question are pointing differences:

compiler is g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)

0

5 Answers 5

6

When you have

string s="hello" + 'c';

It's equal to

string s=("hello" + 'c');

With ASCII encoding it's the same as

string s=("hello" + 99);

which is the same as

string s=(&"hello"[99]);

That is, you get a pointer to the 100:th element of the string "hello", which only have six elements (don't forget the terminator).

Going out of bounds leads to undefined behavior.

Sign up to request clarification or add additional context in comments.

16 Comments

Please create your answer first and then post, don't edit thousand times!
You never win FGITW by doing that ;)
sizeof(s) is the same as sizeof(std::string) which is about as useful as a trapdoor in a canoe. sizeof("hello") is sizeof(const char[6]) which is sizeof(6 * char) which is 6 * sizeof(char) which is 6, as the standard specifies sizeof(char) to be 1.
@Bathsheba But how else would we let the water out? ;)
@infinite That is a completely different matter, and is about namespaces and what happens when you pull in symbols from another namespace. The linked question doesn't mean "strings" in the general case, but simply the std::string class being pulled into the current namespace as string.
|
3

Because "string" is not a std::string but a const char*, and a pointer plus a number (a character is "just" a number) uses pointer arithmetic, so after your addition, you'll get a const char* which points possibly to garbage memory after your string literal.

The second example works because in this case, s is a std::string which has a operator += for char and does not use pointer arithmetic.

Comments

3

The codes are not the same. In

string s="hello" + 'c';

"hello" is not a std::string. It is a string literal and has the type of const char[N]. When you add a character to it to the array decays to a pointer and you are doing pointer arithmetic. That arithmetic is going past the end of the string literal so it is undefined behavior.

In order to get the first code to act like the second example you need to make "hello" a string. You can use a user defined literal for std::string like

string s = "hello"s + 'c';

or just use a constructor call like

string s = std::string("hello") + 'c';

12 Comments

I have edited the question can you please clarify it further.
@infinite We are saying "hello" is not a string/std::string.
then what it is? and why even bother using the 'type' as string for initialization - can you give me some reference text for exact clarification? Thanks in advance
This answer is crystal clear. You're better off researching "string literals in C++"
@infinite Like I said in my answer use "hello"s which makes it a std::string.
|
1

The expression "hello" + 'c'; is adding a char type to a const char[6] type, with an obscure result. Formally the first argument decays to a const char* pointer, and c is added to that pointer using the normal rules of pointer arithmetic. The behaviour is probably undefined, since the numeric value of c is, in all encodings I've ever come across, a value greater than 6, so you end up attempting to index an element outside the const char array "hello".

In the second version, you are exploiting the overloaded += operator of the std::string class taking a char as an argument, and the character c is concatenated to that string.

2 Comments

Hi, I have edited the question so can you please clarify it further?
There's no difference between the type of s generated with std::string s; and using namespace std; string s;. The former should be preferred though due to the namespace polluting effects of the latter.
0

"hello" + 'c' gives a pointer past the end of "hello" (e.g. assuming an ASCII character set, 'c' has the numeric value 99, and "hello" + 99 gives a pointer to a memory location that is 99 characters past the 'h' in "hello").

Using such a pointer to initialise an std::string gives undefined behaviour.

The "CODE 2" works std::string has an operator+=() that accepts a char, and appends it to the end of the string.

Comments