Fundamentally because C++ started its life as "C with classes". Over the years a bunch of new functionality was added and some rules were tightened but C++'s background as an extended C is still clearly visible. In particular.
- The language doesn't make a proper distinction between characters and integers. Type "char" is simply the smallest integer type in the language.
- A regular string literal evaluates to a pointer the first character in a constant array containing a null-terminated string, not to a modern string type.
std::string (strictly the std::basic_string template but lets ignore that detail for now) does it's best to help you. It defines sensible overloads for (again ignoring the detail of rvalue references).
- std::string + std::string
- std::string + char*
- std::string + char
- char* + std::string
- char + std::string
But it can't do anything about operators where neither argument is a std::string. Those work in C++ in the same way they work in C.
- char* + char* --> error
- char + char --> integer addition
- char* + char --> pointer arithmetic
- char + char* --> pointer arithmetic
The result of this is that order of operations becomes very important.
c=c+"#"+a[i];
is equivalent to c=((c+"#")+a[i]);
. This works fine, in the innermost operation one argument is a std::string so the overloaded operators do the right thing and concatenate the arguments to produce another std::string. The same applies when we concatenate the result of that innermost operation to the a[i]
c+="#"+a[i];
is functionally equivalent* to c=(c+("#"+a[i]));
so now we are trying to use the + operator between a string literal which evaluates to a char * and an operation which evaluates to a char. So we add the character code for the character at a[i] to the pointer to the string "#".
since "#" is a rather short string, this will almost certainly result in a pointer that is past the end of the string. This is undefined behaviour by the language spec.
I would guess that "!boxboxbox" is a sandbox error from onlinegdb. It has detected your code doing something it shouldn't and refused to let it go ahead.
Many compilers/linkers put different string data together, so on a regular compiler displaying (part of) another string from the executable (or libraries that it uses) is a likely outcome of running off the end of a string.
C++11 did add support for std::string literals, so one fix could be to add
using namespace std::string_literals;
Then change "#"
to "#"s
* Note that in general with overloaded operators in c++ "+" and "+=" are separate operators and nothing forces the implementer of the class to make them functionally equivalent. Sane class designers generally will though.
Also += may be more efficient as it may be able to perform the concatenation in-place rather than creating a new string.