3

I'm new to C++, and this question will probably seem trivial to many, but please keep in mind I am just starting the C++ language.

I have assigned a variable x to equal 20 and want to concatenate it with a string. My C++ code is below.

#include <iostream>
#include <string>
#include <cmath>
using namespace std;

int main() {
  int x = 20;
  int y = 15;
  if (x >= y) {
    cout << x + " is greater than " + y;
  }
}

My expected outcome would be 20 is greater than 15, but what instead comes up is some odd é@. I'm confused, and I couldn't find a solution on GeeksForGeeks, w3schools, or the rest of SO.

I understand that using cout << x << " is greater than " << y; works just fine, but I'm not sure why concatenation doesn't work here. Also, why do these odd characters come out instead?

Thanks in advance.

(Also, please don't leave an answer without answering the question. I remember when starting JS I asked a question and the only answer was "don't use document.write." While I get that, it would be far better to actually answer the question and put that as a side note.)

Sirswagger21
  • 291
  • 4
  • 17
  • 2
    Hint: Number plus string is not defined. In C++ this is all done through `operator+` definitions. Other languages convert arbitrarily between strings and numbers. C++ in general does not. – tadman Jul 31 '20 at 21:18
  • 1
    Further hint: std::to_string. https://en.cppreference.com/w/cpp/string/basic_string/to_string – George Jul 31 '20 at 21:19
  • Simple enough, adding an integer to a string literal does not do concatenation. Instead you are (without knowing it) doing *pointer arithmetic*. – john Jul 31 '20 at 21:19
  • 1
    float + int is defined, and triggers conversion. string + other things is not concatenation and does not trigger conversion. In C++ don't assume type conversion happens automatically – Dave S Jul 31 '20 at 21:19
  • Ok, thanks @DaveS. I guess C++ is different in that aspect from Javascript, python, etc. – Sirswagger21 Jul 31 '20 at 21:21
  • Yep, it is more "strongly typed" than loosely typed scripting languages where 2 + "40" = 42. – Dave S Jul 31 '20 at 21:22
  • @FruDe C++ is different from every other language. It's very very different from javascript and python – john Jul 31 '20 at 21:22
  • @john Well from what I've seen so far, some aspects are similar to JS, loops are essentially the same for example. But yes, I get your point – Sirswagger21 Jul 31 '20 at 21:23
  • @FruDe weak typing vs strong typing, garbage collection vs destructors are the differences that imediately come to mind. C++ is also far more complicated. – john Jul 31 '20 at 21:25
  • 1
    You are given a gun without a safety. Please use responsibly - and make sure to wear bullet proof shoes as you will shoot yourself in the foot for the rest of your career - we all do :) http://www.toodarkpark.org/computers/humor/shoot-self-in-foot.html – Michael Dorgan Jul 31 '20 at 21:27
  • I'd also expect your book to explain this. If you don't have one, get one! – Asteroids With Wings Jul 31 '20 at 21:29
  • 3
    you can try `std::to_string(x) + " is greater than " + std::to_string(y)` to make it works. – Picaud Vincent Jul 31 '20 at 21:30
  • 3
    Better hint: Number + string is defined, but not the way you think. – gnasher729 Jul 31 '20 at 21:31
  • Hi @PicaudVincent please don't answer in the comments section. :) That's quite an expensive solution (potentially) if you're going to stream the result anyway – Asteroids With Wings Jul 31 '20 at 21:31
  • Just wait until you get hit in the face with code like `10[array]` which resolves to `*(10 + array)` and is equivalent to the more recognizable `array[10]`. – user4581301 Jul 31 '20 at 21:37
  • @tadman Re: `Number plus string is not defined.` But `char*` plus number is. The OP's test unfortunately pointed pass the text, but try this: ` int x = 4; std::cout << x + " is greater than "; ` – Vlad Feinstein Jul 31 '20 at 22:08

1 Answers1

5

The reason you get some weird output is a part of C++'s history being an evolution of C. In the expression x + " is greater than " + y the expression " is greater than " is a const char* literal which is a raw C-style type. It is not a C++ class type like std::string due to backwards compatibility reasons.

Your + signs add integers to a const char*. This results in pointer arithmetic. Basically, " is greater than " being a const char*, it is a pointer to some buffer of memory whose contents are ASCII bytes for " is greater than ". The effect of adding x and y to that is to move the pointer to the right 35 bytes where it will go off the end of the buffer and read uninitialized memory. That is the "odd characters" that come out. Properly speaking this is undefined behavior so anything could happen. In real systems though this will just be a buffer overflow read resulting in gibberish characters.

As others have noted, a way to fix this would be to use std::to_string on the integers. Then, instead of int + const char* + int you would get std::string + const char* + std::string which is handled much better.

If this is unclear you can look up pointers, C-style strings, and buffer overflows for more info.

Edit: Technically speaking string literals are const char[] but I have omitted this for clarity.

jcai
  • 3,448
  • 3
  • 21
  • 36