Why Can't I Write to a String Literal While I *Can* Write to a String Object

Why can't I write to a string literal while I *can* write to a string object?

Because "Hello" creates a const char[]. This decays to a const char* not a char*. In C++ string literals are read-only. You've created a pointer to such a literal and are trying to write to it.

But when you do

string s1 = "hello";

You copy the const char* "hello" into s1. The difference being in the first example s1 points to read-only "hello" and in the second example read-only "hello" is copied into non-const s1, allowing you to access the elements in the copied string to do what you wish with them.

If you want to do the same with a char* you need to allocate space for char data and copy hello into it

char hello[] = "hello"; // creates a char array big enough to hold "hello"
hello[0] = 'w'; // writes to the 0th char in the array

Why is #include string needed for string objects but not string literals?

A string literal is not a std::string object, it's an array of const char.

"This is a string literal" has the type const char[25].

In most situations – including this one – an array implicitly decays into a pointer to its first element, and there is an operator<< overload for const char*.

It's pretty confusing that "string" means several different things in C++, but after a while (and pulling of hair and gnashing of teeth) the intended meaning will be clear from context.

Can't understand how Java string literals are implemented

15.18.1. String Concatenation Operator +


An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

In your case,

String s1 = "hello";
String s2 ="bc";
int value = 22;

String r = s1 + s2 + value;

you will get

INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ILOAD 3
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;

While concatinating constant objects

String r = "hello" + "bc" + 22;

you will get

LDC "hellobc22"
ASTORE 2

When the compiler "meets" this code:

String s = s1+s2+22;

it "changes" it to:

String s = new StringBuilder().append("hello").append("bc").append(22).toString();

No. It may optimise it to

String s = new StringBuilder().append(s1).append(s2).append(value).toString();

but it can't replace s1 with "hello" because there is no guarantee the variable will keep referring to "hello". The variable is not final and thus open to reassignment.

Strings are objects in Java, so why don't we use 'new' to create them?

In addition to what was already said, String literals [ie, Strings like "abcd" but not like new String("abcd")] in Java are interned - this means that every time you refer to "abcd", you get a reference to a single String instance, rather than a new one each time. So you will have:

String a = "abcd";
String b = "abcd";

a == b; //True

but if you had

String a = new String("abcd");
String b = new String("abcd");

then it's possible to have

a == b; // False

(and in case anyone needs reminding, always use .equals() to compare Strings; == tests for physical equality).

Interning String literals is good because they are often used more than once. For example, consider the (contrived) code:

for (int i = 0; i < 10; i++) {
System.out.println("Next iteration");
}

If we didn't have interning of Strings, "Next iteration" would need to be instantiated 10 times, whereas now it will only be instantiated once.

Why do I get a segmentation fault when writing to a char *s initialized with a string literal, but not char s[] ?

See the C FAQ, Question 1.32

Q: What is the difference between these initializations?

char a[] = "string literal";
char *p = "string literal";
My program crashes if I try to assign a new value to p[i].

A: A string literal (the formal term
for a double-quoted string in C
source) can be used in two slightly
different ways:

  1. As the initializer for an array of char, as in the declaration of char a[] , it specifies the initial values
    of the characters in that array (and,
    if necessary, its size).
  2. Anywhere else, it turns into an unnamed, static array of characters,
    and this unnamed array may be stored
    in read-only memory, and which
    therefore cannot necessarily be
    modified. In an expression context,
    the array is converted at once to a
    pointer, as usual (see section 6), so
    the second declaration initializes p
    to point to the unnamed array's first
    element.

Some compilers have a switch
controlling whether string literals
are writable or not (for compiling old
code), and some may have options to
cause string literals to be formally
treated as arrays of const char (for
better error catching).

In Java, is there a way to write a string literal without having to escape quotes?

The answer is no, and the proof resides in the Java Language Specification:

  StringLiteral:
"StringCharacters"

StringCharacters:
StringCharacter
| StringCharacters StringCharacter

StringCharacter:
InputCharacter but not " or \
| EscapeSequence

As you can see a StringLiteral can just be bound by " and cannot contain special character without escapes..

A side note: you can embed Groovy inside your project, this will extend the syntax of Java allowing you to use '''multi line string ''', ' "string with single quotes" ' and also "string with ${variable}".

Creating multiline strings in JavaScript

Update:

ECMAScript 6 (ES6) introduces a new type of literal, namely template literals. They have many features, variable interpolation among others, but most importantly for this question, they can be multiline.

A template literal is delimited by backticks:

var html = `
<div>
<span>Some HTML here</span>
</div>
`;

(Note: I'm not advocating to use HTML in strings)

Browser support is OK, but you can use transpilers to be more compatible.


Original ES5 answer:

Javascript doesn't have a here-document syntax. You can escape the literal newline, however, which comes close:

"foo \
bar"

python: SyntaxError: EOL while scanning string literal

You are not putting a " before the end of the line.

Use """ if you want to do this:

""" a very long string ...... 
....that can span multiple lines
"""


Related Topics



Leave a reply



Submit