Bug 8660 – Unclear semantics of array literals of char type, vs string literals

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-09-14T04:28:17Z
Last change time
2024-12-13T18:01:24Z
Assigned to
No Owner
Creator
Don
Blocks
8659
See also
https://issues.dlang.org/show_bug.cgi?id=24330
Moved to GitHub: dmd#17556 →

Comments

Comment #0 by clugdbug — 2012-09-14T04:28:17Z
Array literals of char type, have completely different semantics from string literals. In module scope: char[] x = ['a']; // OK -- array literals can have an implicit .dup char[] y = "b"; // illegal A second difference is that string literals have a trailing \0. It's important for compatibility with C, but is barely mentioned in the spec. The spec does not state if the trailing \0 is still present after operations like concatenation. CTFE can use either, but it has to choose one. This leads to odd effects: string foo(bool b) { string c = ['a']; string d = "a"; if (b) return c ~ c; else return c ~ d; } char[] x = foo(true); // ok char[] y = foo(false); // rejected! This is really bizarre because at run time, there is no difference between foo(true) and foo(false). They both return a slice of something allocated on the heap. I think x = foo(true) should be rejected as well, it has an implicit cast from immutable to mutable. I think the best way to clean up this mess would be to convert char[] array literals into string literals whenever possible. This would mean that string literals may occasionally be of *mutable* type! This would means that whenever they are assigned to a mutable variable, an implicit .dup gets added (just as happens now with array literals). The trailing zero would not be duped. ie: A string literal of mutable type should behaves the way a char[] array literal behaves now. A char[] array literal of immutable type should behave the way a string literal does now.
Comment #1 by timon.gehr — 2012-09-14T08:42:57Z
I don't have a deep understanding of the DMD CTFE engine, but wouldn't it suffice to do a conversion to a string literal if the type is immutable(char)[] and to an array literal otherwise? This would only have to be done once (recursively on the entire return value) as a final sanitizing step after the CTFE execution has run to completion. This would make both lines illegal, as you suggest.
Comment #2 by clugdbug — 2012-09-17T08:28:43Z
(In reply to comment #1) > I don't have a deep understanding of the DMD CTFE engine, but wouldn't it > suffice to do a conversion to a string literal if the type is immutable(char)[] > and to an array literal otherwise? This would only have to be done once > (recursively on the entire return value) as a final sanitizing step after the > CTFE execution has run to completion. This would make both lines illegal, as > you suggest. Yes (in fact a sanitizing step already exists, that's where pointers are checked, for example). It wouldn't work for D1, though, which doesn't have immutable, and for which this compiles: char [] s = "abc"; char [] t = ['a','b','c']; (Yuck!)
Comment #3 by robert.schadek — 2024-12-13T18:01:24Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17556 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB