0

It seems the << operator is able to stream two string literals to cout side by side whereas it's not able to stream two string variables side by side because two string literals are implicitly concatenated whereas two string variables are not. Here's a code example to showcase this:

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

int main() {
    string string1 = "C";
    string string2 = "D";

    cout << "A" "B"; //This compiles and outputs "AB"
    cout << string1 string2; //This doesn't compile

    return 0;
}

As noted in the comments the line cout << "A" "B"; compiles and outputs "AB". There seems to be some sort of implicit concatenation of these two string literals. But the next line doesn't not compile. That seems to indicate that a lack of that same implicit concatenation for some reason.

Why does the compiler treat these two lines differently? If it's concatenating string literals, shouldn't it also concatenate string variables?

What is happening implicitly and why doesn't it happen to both string literals and variables?

EDIT: It does seem close to the linked possible duplicate question but that question asks "Why is this behavior (implicit concatenation of string literals) in the language?" whereas mine asks, "Why is this done with string literals but not string variables.

Patrick
  • 11,552
  • 7
  • 29
  • 41
  • 4
    This has nothing to do with `<<`. – melpomene Oct 18 '17 at 22:53
  • 1
    Maybe this helps: [How does concatenation of two string literals work?](https://stackoverflow.com/questions/12120944/how-does-concatenation-of-two-string-literals-work) – WhozCraig Oct 18 '17 at 22:54
  • @WhozCraig Thank you! That helps answer why the string literals are concatenated but why are string literals treated differently than string variables in this respect? – Patrick Oct 18 '17 at 22:57
  • 1
    The literals form one string (the type will be `const char*`). The preprocessor concats them if i'm not mistaken, so the compiler sees one string. For the `std::string`s they are always 2 strings (string class objects the compiler itself does nothing special with) and they need another `<<` in between them for it to be valid syntax. – Paul Rooney Oct 18 '17 at 23:00
  • @PaulRooney according to the C89 Commitee, "An explicit concatenation operator was not introduced because the concatenation is a lexical construct rather than a run-time operation." Why would string literal concatenation be considered a lexical construct while string variable concatenation is considered a runtime operation? – Patrick Oct 18 '17 at 23:03
  • 3
    It's a feature. The compiler knows that the only thing syntactically valid to do with two string literals is to concatenate them. If it has two symbols without an operator in between it's much more indeterminate. – Mark Ransom Oct 18 '17 at 23:03
  • It was a mistake to make the first one work. Don't use it. – Patrick87 Oct 18 '17 at 23:08
  • @MarkRansom Thank you! That's exactly the information I was looking for (even if I didn't know how to quite ask the question (I've updated the question now to better reflect the information requested)). The question seems different than the one linked to but is it close enough to a duplicate that I should delete it? If not, do you want to add your response as an answer and I'll mark it as the answer? – Patrick Oct 18 '17 at 23:16
  • @PaulRooney: The type of a string literal is `const char[N]`, where N is the length plus 1. It decays to `const char*` in some but not all contexts. – Keith Thompson Oct 19 '17 at 00:06
  • 1
    If you're going to downvote, please let me know why you did so I can improve the question. If it was because it was flagged as a duplicate, please explain why my explanation of why it's not a duplicate is incorrect. – Patrick Oct 19 '17 at 01:16
  • Now I'm wondering if anything would break if this were specified to happen during phase 7 (compilation) rather than phase 6. – aschepler Oct 19 '17 at 11:35
  • 1
    @Patrick: "*Why would string literal concatenation be considered a lexical construct while string variable concatenation is considered a runtime operation?*" - because string literals are known to the preprocessor/compiler at compile time, so it is very easy for them to concatenate consecutive literals of the same type together, whereas `std::string` is a class type so instances of it are constructed only at runtime and concatenation requires a function call to `operator+`. – Remy Lebeau Oct 19 '17 at 21:12
  • Thanks @RemyLebeau that helps pieces together the information I've received. – Patrick Oct 19 '17 at 23:53

1 Answers1

2

Concatenation of string literals happens at compile time, in fact very early in the process of compilation, while concatenation of std::string requires generating code which calls an overloaded operator on std::string (std::basic_string<T>::operator+). Concatenation of string literals is a surface level syntactic feature which can be handled just above tokenization in C-based languages. It comes from C, not C++ and C originally didn't even have string concatenation with automatic memory allocation in its library.

(It is instructive to go through the low-level calls that happen in the following:

std::string a("a");
std::string a("b");

auto foo = a + b;
auto bar = a + "b";
auto baz = std::string("a") + b;

)

With constexpr, it might be possible to evaluate concatenation of constant strings at compile time even using std::string but one should appreciate all the machinery involved in doing so and certainly that parts of it are only fairly recent additions to C++.

In order for C++ to support the type of concatenation proposed transparently on std::string, one would have to be able to overload the "whitespace operator." See the following April Fools proposal: http://www.stroustrup.com/whitespace98.pdf .

Zalman Stern
  • 3,161
  • 12
  • 18
  • Thank you! The detail is very much appreciated. I even learned Stroustrup has a sense a humor :) – Patrick Oct 19 '17 at 21:04