0

I have read numerous posts as to why two string literals cannot be added in C++, etc, and the operator+ support adding a string literal to an integer.

However, I am trying to understand the compiler error in the following code:

string str1, str2, str3;
int i = 10;

str1 = "Hello " + i;
str2 = i + "Mars";
str3 = "Hello " + i + "Mars";

Initialization of str1 and str2 works fine, but the construction of str3 gives the following error:

example.cpp: In function int main():
example.cpp:20:27: error: invalid operands of types const char* and const char [5] to binary operator+

Q1: In the error message, I understand const char [5] refers to "Mars". What does const char* refer to, the integer i after conversion to a char *?

Q2: operator+ has left-to-right associativity, I am guessing the construction of str3 can be written as:

str3 = ("Hello " + i) + "Mars";

Does ("Hello " + i) evaluate to a char *?

Q3: In the following code:

str5 = string("foo ") + "bar ";
str6 = string("foo ") + "bar " + i;

Setting of str5 compiles fine, but str6 generates loads (page and half) of error messages. What is the outcome of string("foo ") + "bar ", is it a "string"?

Thanks in advance for any insight.

GSerg
  • 76,472
  • 17
  • 159
  • 346
Ahmed A
  • 3,362
  • 7
  • 39
  • 57
  • 2
    You are trying to add a string and an integer. That's the error. Consider : http://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c – squiguy Apr 16 '13 at 21:46

3 Answers3

7

str1 takes the string literal (really an array of constant characters), decays it to a pointer to the first character, and adds ten to that pointer, resulting in a const char * that's outside of your string literal, which is undefined behaviour, since it's beyond one past the end.

str2 does the same thing as str1, but goes even farther out of bounds.

str3 does the same thing with "Hello" and i, and then tries to add the resulting const char * to your other string literal (again, an array of constant characters, which is decayed due to being passed into a function). There's no overload of operator+ that will take const char * and const char *, thus you get errors.

Take note that none of these will work as you want them to. The ones that do compile are undefined behaviour. std::string has overloaded operator+ to suit its purposes, so adding a string literal to a std::string just concatenates it. To add an integer is a bit ambiguous, though (and thus not supported with operator+), so you have to make your intent clear by converting it to a string first:

str6 = string("foo ") + "bar " + std::to_string(i);
chris
  • 60,560
  • 13
  • 143
  • 205
3

Q1: In the error message, I understand const char [5]' refers to "Mars". What doesconst char*' refer to, the integer i after conversion to a "char *"?

It refers to the result of "Hello" + i.

Q2: operator+ has left-to-right associativity, I am guessing the construction of str3 can be written as: str3 = ("Hello " + i) + "Mars";

Does ("Hello " + i) evaluate to a char *?

Yes. It evaluates to const char*, though.

Q3: What is the outcome of string("foo ") + "bar ", is it a "string"?

Yes, it's a std:string. You get an error in str6 = string("foo ") + "bar " + i; because you can't add a string and an integer.

A side note - none of the following three statements is iniatialization:

str1 = "Hello " + i;
str2 = i + "Mars";
str3 = "Hello " + i + "Mars";

They all call assignment operator.

jrok
  • 54,456
  • 9
  • 109
  • 141
  • However it is valid to add a string literal to an integer (as seen by setting of str1 in my main post). I am curious, as to why that was not implemented, adding a string to an integer. – Ahmed A Apr 16 '13 at 21:54
  • 2
    @AhmedA, For `std::string`, do you want to increase its length by that number? Concatenate the number? Add a character with that numeric value? It's really better as a separate operation. As for the literal, it takes on the necessary pointer arithmetic. – chris Apr 16 '13 at 21:56
  • @AhmedA It's valid, but only if you're not adding more than the length of the literal (see chris's post). It does not do concatenation, though, it increments the pointer to the literal. – jrok Apr 16 '13 at 21:56
  • Please ignore my last question, figured out the outcome of adding an int to an string literal. – Ahmed A Apr 16 '13 at 21:58
1

The thing is, "Hello" the literal is treated as a char*. You can do pointer arithmetic on a char* by adding an int to it -- you're saying "10 chars beyond what the char* points to". In other words, garbage.

In short, you need to be using boost::lexical_cast or istringstream for this kind of thing.

Nathan Monteleone
  • 5,430
  • 29
  • 43
  • Ah ok, I just noticed when I printed "Hello" + 10, it is not "Hello" + "10", but as you pointed out, the value is garbage. Thank you. – Ahmed A Apr 16 '13 at 21:57
  • 1
    @AhmedA try `std::cout << ("Hello" + 1) << std::endl;` to get a clearer understanding of what happens. – Nik Bougalis Apr 16 '13 at 22:05