Skip to content

Commit 1fcb6d4

Browse files
authored
[spec] Improve string literal docs (#3662)
* [spec] Improve string literal docs Link to lex StringLiteral rather than repeating grammar. Move semantic sentences about string literals being read-only to expression.dd. Mention string literal can convert to an lvalue (as already shown in the example). Show literal arguments in example. Document that the null byte can be used to match a static array when necessary. * Document that StringPostfix disables implicit conversions Part of Issue 6032 - wstring literals cannot be implicitly converted to const(wchar)* * Move EscapeSequence and StringPostfix to their headings * Literal can convert to static array rvalue of longer length Null-termination is not relevant. Also remove slicing from example, documented elsewhere.
1 parent 56a5066 commit 1fcb6d4

File tree

2 files changed

+58
-61
lines changed

2 files changed

+58
-61
lines changed

spec/expression.dd

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ $(GNAME PrimaryExpression):
17471747
$(GLINK_LEX IntegerLiteral)
17481748
$(GLINK_LEX FloatLiteral)
17491749
$(LEGACY_LNAME2 CharacterLiteral)$(LEGACY_LNAME2 character-literal)$(GLINK_LEX CharacterLiteral)
1750-
$(GLINK_LEX StringLiteral)
1750+
$(RELATIVE_LINK2 string_literals, *StringLiteral*)
17511751
$(GLINK ArrayLiteral)
17521752
$(GLINK AssocArrayLiteral)
17531753
$(GLINK FunctionLiteral)
@@ -1842,19 +1842,14 @@ $(H3 $(LNAME2 null, null))
18421842
but no longer exact.
18431843
)
18441844

1845-
$(H3 $(LNAME2 string_literals, String Literals))
1845+
$(H3 $(LEGACY_LNAME2 StringLiteral, string_literals, String Literals))
18461846

1847-
$(GRAMMAR_INFORMATIVE
1848-
$(GNAME StringLiteral):
1849-
$(GLINK_LEX WysiwygString)
1850-
$(GLINK_LEX AlternateWysiwygString)
1851-
$(GLINK_LEX DoubleQuotedString)
1852-
$(GLINK_LEX DelimitedString)
1853-
$(GLINK_LEX TokenString)
1854-
)
1847+
$(P See $(GLINK_LEX StringLiteral) grammar.)
18551848

1856-
$(P String literals can implicitly convert to any
1857-
of the following types, they have equal weight:
1849+
$(P String literals are read-only.
1850+
A string literal without a $(DDSUBLINK spec/lex, string_postfix, StringPostfix)
1851+
can implicitly convert to any
1852+
of the following types, which have equal weight:
18581853
)
18591854

18601855
$(TABLE
@@ -1866,39 +1861,46 @@ $(GNAME StringLiteral):
18661861
$(TROW $(D immutable(dchar)[]))
18671862
)
18681863

1864+
$(UNDEFINED_BEHAVIOR writing to a string literal. This is not allowed in `@safe` code.)
1865+
18691866
$(P By default, a string literal is typed as a dynamic array, but the element
18701867
count is known at compile time. So all string literals can be
1871-
implicitly converted to static array types.)
1868+
implicitly converted to an immutable static array:)
18721869

1870+
$(SPEC_RUNNABLE_EXAMPLE_RUN
18731871
-------------
18741872
void foo(char[2] a)
18751873
{
1876-
assert(a == "bc");
1874+
assert(a[0] == 'b');
18771875
}
18781876
void bar(ref const char[2] a)
18791877
{
18801878
assert(a == "bc");
18811879
}
1882-
void baz(const char[3] a) {}
18831880

18841881
void main()
18851882
{
1886-
string str = "abc";
1887-
foo(str[1 .. 3]);
1888-
bar(str[1 .. 3]);
1889-
//baz(str[1 .. 3]); // cannot match length
1883+
foo("bc");
1884+
foo("b"); // OK
1885+
//foo("bcd"); // error, too many chars
1886+
bar("bc"); // OK, same length
1887+
//bar("b"); // error, lengths must match
18901888
}
18911889
-------------
1892-
1893-
$(P String literals have a 0 appended to them, which makes
1894-
them easy to pass to C or C++ functions expecting a $(CODE const char*)
1895-
string.
1896-
The 0 is not included in the $(CODE .length) property of the
1890+
)
1891+
$(P A string literal converts to a static array rvalue of the same or longer length.
1892+
Any extra elements are padded with zeros. A string literal
1893+
can also convert to a static array lvalue of the same length.)
1894+
1895+
$(P String literals have a `'\0'` appended to them, which makes
1896+
them easy to pass to C or C++ functions expecting a null-terminated
1897+
$(CODE const char*) string.
1898+
The `'\0'` is not included in the $(CODE .length) property of the
18971899
string literal.
18981900
)
18991901

1900-
$(P Concatenation of string literals requires the use of the
1901-
`~` operator, and is resolved at compile time.
1902+
$(P Concatenation of string literals requires the use of
1903+
$(RELATIVE_LINK2 cat_expressions, the `~` operator), and is resolved at compile time.
19021904
C style implicit concatenation without an intervening operator is
19031905
error prone and not supported in D.)
19041906

spec/lex.dd

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -289,50 +289,17 @@ $(GNAME StringLiteral):
289289
$(GLINK WysiwygString)
290290
$(GLINK AlternateWysiwygString)
291291
$(GLINK DoubleQuotedString)
292-
293292
$(GLINK DelimitedString)
294293
$(GLINK TokenString)
295294
)
296295
$(P
297-
A string literal is either a double quoted string, a wysiwyg quoted
296+
A string literal is either a wysiwyg quoted string, a double quoted
298297
string, a delimited string, or a token string.
299298
)
300299

301300
$(P In all string literal forms, an $(GLINK EndOfLine) is regarded as a single
302301
$(D \n) character.)
303302

304-
$(P String literals are read only.)
305-
306-
$(UNDEFINED_BEHAVIOR writing to a string literal. This is not allowed in `@safe` code.)
307-
308-
$(GRAMMAR_LEX
309-
$(GNAME EscapeSequence):
310-
$(B \\')
311-
$(B \\")
312-
$(B \\?)
313-
$(B \\\\)
314-
$(B \0)
315-
$(B \a)
316-
$(B \b)
317-
$(B \f)
318-
$(B \n)
319-
$(B \r)
320-
$(B \t)
321-
$(B \v)
322-
$(B \x) $(GLINK HexDigit) $(GLINK HexDigit)
323-
$(B \\) $(GLINK OctalDigit)
324-
$(B \\) $(GLINK OctalDigit) $(GLINK OctalDigit)
325-
$(B \\) $(GLINK OctalDigit) $(GLINK OctalDigit) $(GLINK OctalDigit)
326-
$(B \u) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit)
327-
$(B \U) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit)
328-
$(B \\) $(GLINK2 entity, NamedCharacterEntity)
329-
330-
$(GNAME StringPostfix):
331-
$(B c)
332-
$(B w)
333-
$(B d)
334-
)
335-
336303
$(H3 $(LNAME2 wysiwyg, Wysiwyg Strings))
337304
$(GRAMMAR_LEX
338305
$(GNAME WysiwygString):
@@ -526,6 +493,13 @@ $(GNAME TokenStringToken):
526493

527494
$(H3 $(LNAME2 string_postfix, String Postfix))
528495

496+
$(GRAMMAR_LEX
497+
$(GNAME StringPostfix):
498+
$(B c)
499+
$(B w)
500+
$(B d)
501+
)
502+
529503
$(P The optional $(I StringPostfix) character gives a specific type
530504
to the string, rather than it being inferred from the context.
531505
The types corresponding to the postfix characters are:
@@ -551,7 +525,28 @@ $(H3 $(LNAME2 string_postfix, String Postfix))
551525

552526
$(H2 $(LNAME2 escape_sequences, Escape Sequences))
553527

554-
$(P The escape sequences listed in $(GLINK EscapeSequence) are:)
528+
$(GRAMMAR_LEX
529+
$(GNAME EscapeSequence):
530+
$(B \\')
531+
$(B \\")
532+
$(B \\?)
533+
$(B \\\\)
534+
$(B \0)
535+
$(B \a)
536+
$(B \b)
537+
$(B \f)
538+
$(B \n)
539+
$(B \r)
540+
$(B \t)
541+
$(B \v)
542+
$(B \x) $(GLINK HexDigit) $(GLINK HexDigit)
543+
$(B \\) $(GLINK OctalDigit)
544+
$(B \\) $(GLINK OctalDigit) $(GLINK OctalDigit)
545+
$(B \\) $(GLINK OctalDigit) $(GLINK OctalDigit) $(GLINK OctalDigit)
546+
$(B \u) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit)
547+
$(B \U) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit) $(GLINK HexDigit)
548+
$(B \\) $(GLINK2 entity, NamedCharacterEntity)
549+
)
555550

556551
$(LONGTABLE_2COLS 0.8, Escape Sequences,
557552
$(THEAD Sequence, Meaning),

0 commit comments

Comments
 (0)