0

I do really wonder why this program compiles and run correctly:

int main(){

    std::string(foo)("strange" " string " "declaration");
    std::cout << foo << std::endl;

     return 0;
}

It will print:

strange string declaration
WonFeiHong
  • 445
  • 4
  • 16
  • 6
    What's so strange about it? – axiac Jan 01 '18 at 22:09
  • 1
    @axiac, Let's be real here. Neither of these is too common in C++ code, so unfamiliarity is pretty expected. I'm not sure if that's what you were getting at, or just trying to get the question to be more specific, which I can get behind. @OP, focusing on the extra parentheses, one way to make sense of it is that C's declaration syntax models use: `(foo)` is of type `string`. – chris Jan 01 '18 at 22:12
  • Since you did not tell use what exactly you find strange, I picked the "strangest" thing in the post. If that was not what you consider strange, please clarify your question. – Baum mit Augen Jan 01 '18 at 22:13
  • Adjacent string literals (separated by whitespace only) are implicitly concatenated by the preprocessor. More information: http://en.cppreference.com/w/c/language/string_literal – mdatsev Jan 01 '18 at 22:13
  • @Baum There are at least two issues here - your dupe only addresses one. –  Jan 01 '18 at 22:15
  • 2
    **String literals placed side-by-side are concatenated at translation phase 6 (after the preprocessor). That is, "Hello," " world!" yields the (single) string "Hello, world!"** http://en.cppreference.com/w/cpp/language/string_literal – Killzone Kid Jan 01 '18 at 22:16
  • @NeilButterworth Lacking a clear question in the OP, I had to guess what exactly was considered strange here. Most people probably don't consider that string concatenation strange, but we can add a dupe for that, too if you want. – Baum mit Augen Jan 01 '18 at 22:17
  • @NeilButterworth There you go: https://stackoverflow.com/q/39327148/3002139 Was that really worth reopening for that? :/ – Baum mit Augen Jan 01 '18 at 22:18
  • @Baum It was worth re-opening because the reason for closing it was obviously not the thrust of the OP's question. I have no problem with it being closed now that you have identified a question that addresses the OPs problem. –  Jan 01 '18 at 22:22
  • @NeilButterworth I can't close it anymore because I already did once, but go right ahead please. – Baum mit Augen Jan 01 '18 at 22:23
  • @NeilButterworth - You really think the string concatenation was the surprising part? I am amazed. – Martin Bonner supports Monica Jan 02 '18 at 09:28

2 Answers2

4

This is because the strings are being processed by the C preprocessor. When you have strings like this:

"foo" "bar"

the preprocessor turns them into

"foobar"

which is then passed on to the C or C++ compiler. This is handy if you want to have long string literals, and still keep them readable:

"this is a very long string literal that goes on and on and on and on"
" and then stops"
  • So no `\\` needed between lines? – WonFeiHong Jan 01 '18 at 22:14
  • @Won No - the preprocessor ignores any whitespace (including newlines) between string literals. –  Jan 01 '18 at 22:16
  • I meant this way I don't need to add \ to tell the pre-processor that the remaining text is on the next line. – WonFeiHong Jan 01 '18 at 22:18
  • 1
    @WonFeiHong, Line continuations (`\\` followed by a newline) are used for splitting one token into multiple lines or continuing a piece of code that must remain on a single line (like a macro definition). This literal concatenation technique breaks the literal into two tokens, so there's no need for a continuation. – chris Jan 01 '18 at 22:18
  • Yes that is it. Thank you. – WonFeiHong Jan 01 '18 at 22:19
0

It is because declarations and definitions can have extraneous parenthesis. In this case the parens around foo don't do anything.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23