Why must C/C++ string literal declarations be single-line?

假如想象 提交于 2019-12-13 11:53:14

问题


Is there any particular reason that multi-line string literals such as the following are not permitted in C++?

string script =
"
      Some
   Formatted
 String Literal
";

I know that multi-line string literals may be created by putting a backslash before each newline. I am writing a programming language (similar to C) and would like to allow the easy creation of multi-line strings (as in the above example).

Is there any technical reason for avoiding this kind of string literal? Otherwise I would have to use a python-like string literal with a triple quote (which I don't want to do):

string script =
"""
      Some
   Formatted
 String Literal
""";

Why must C/C++ string literal declarations be single-line?


回答1:


One has to consider that C was not written to be an "Applications" programming language but a systems programming language. It would not be inaccurate to say it was designed expressly to rewrite Unix. With that in mind, there was no EMACS or VIM and your user interfaces were serial terminals. Multiline string declarations would seem a bit pointless on a system that did not have a multiline text editor. Furthermore, string manipulation would not be a primary concern for someone looking to write an OS at that particular point in time. The traditional set of UNIX scripting tools such as AWK and SED (amongst MANY others) are a testament to the fact they weren't using C to do significant string manipulation.

Additional considerations: it was not uncommon in the early 70s (when C was written) to submit your programs on PUNCH CARDS and come back the next day to get them. Would it have eaten up extra processing time to compile a program with multiline strings literals? Not really. It can actually be less work for the compiler. But you were going to come back for it the next day anyhow in most cases. But nobody who was filling out a punch card was going to put large amounts of text that wasn't needed in their programs.

In a modern environment, there is probably no reason not to include multiline string literals other than designer's preference. Grammatically speaking, it's probably simpler because you don't have to take linefeeds into consideration when parsing the string literal.




回答2:


The terse answer is "because the grammar prohibits multiline string literals." I don't know whether there is a good reason for this other than historical reasons.

There are, of course, ways around this. You can use line splicing:

const char* script = "\
      Some\n\
   Formatted\n\
 String Literal\n\
";

If the \ appears as the last character on the line, the newline will be removed during preprocessing.

Or, you can use string literal concatenation:

const char* script = 
"      Some\n"
"   Formatted\n"
" String Literal\n";

Adjacent string literals are concatenated during preprocessing, so these will end up as a single string literal at compile-time.

Using either technique, the string literal ends up as if it were written:

const char* script = "      Some\n   Formatted\n  String Literal\n";



回答3:


Others have mentioned some excellent workarounds, I just wanted to address the reason.

The reason is simply that C was created at a time when processing was at a premium and compilers had to be simple and as fast as possible. These days, if C were to be updated (I'm looking at you, C1X), it's quite possible to do exactly what you want. It's unlikely, however. Mostly for historical reasons; such a change could require extensive rewrites of compilers, and so will likely be rejected.




回答4:


In addition to the existing answers, you can work around this using C++11's raw string literals, e.g.:

#include <iostream>
#include <string>

int main() {
   std::string str = R"(a
b)";
   std::cout << str;
}

/* Output:
a
b
*/

Live demo.


[n3290: 2.14.5/4]: [ Note: A source-file new-line in a raw string literal results in a new-line in the resulting execution string-literal. Assuming no whitespace at the beginning of lines in the following example, the assert will succeed:

const char *p = R"(a\
b
c)";
assert(std::strcmp(p, "a\\\nb\nc") == 0);

—end note ]

Though non-normative, this note and the example that follows it in [n3290: 2.14.5/5] serve to complement the indication in the grammar that the production r-char-sequence may contain newlines (whereas the production s-char-sequence, used for normal string literals, may not).




回答5:


The C preprocessor works on a line-by-line basis, but with lexical tokens. That means that the preprocessor understands that "foo" is a token. If C were to allow multi-line literals, however, the preprocessor would be in trouble. Consider:

"foo
#ifdef BAR
bar
#endif
baz"

The preprocessor isn't able to mess with the inside of a token - but it's operating line-by-line. So how is it supposed to handle this case? The easy solution is to simply forbid multiline strings entirely.




回答6:


Actually, you can break it up thus:

string script =
"\n"
"      Some\n"
"   Formatted\n"
" String Literal\n";

Adjacent string literals are concatenated by the compiler.




回答7:


Strings can lay on multiple lines, but each line has to be quoted individually :

string script =
    "                \n"
    "       Some     \n"
    "    Formatted   \n"
    " String Literal ";



回答8:


I am writing a programming language (similar to C) and would like to let write multi-line strings easily (like in above example).

There is no reason why you couldn't create a programming language that allows multi-line strings. For example, Vedit Macro Language (which is C-like scripting language for VEDIT text editor) allows multi-line strings, for example:

Reg_Set(1,"
      Some
   Formatted
 String Literal
")

It is up to you how you define your language syntax.




回答9:


You can also do:

string useMultiple =  "this" 
                      "is "
                      "a string in C."; 

Place one literal after another without any special chars.




回答10:


Literal declarations doesn't have to be single-line.

GPUImage inlines multiline shader code. Checkout its SHADER_STRING macro.



来源:https://stackoverflow.com/questions/3093632/why-must-c-c-string-literal-declarations-be-single-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!