digitalmars.D.learn - Type of string literal concatenated with non-immutable char array
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (36/36) Jan 31 2021 Given
- Jacob Carlborg (24/52) Feb 01 2021 Because if you have arrays of reference types, it's possible to
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (6/14) Feb 01 2021 I still don't understand why that restriction applies to arrays
- ag0aep6g (8/23) Feb 01 2021 If concatenation is guaranteed to allocate a new array, then it should
- Steven Schveighoffer (5/15) Feb 01 2021 It is. https://dlang.org/spec/arrays.html#array-concatenation
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (5/7) Feb 01 2021 Btw, does
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (2/5) Feb 01 2021 Provided all the operands has a `length` property.
- Steven Schveighoffer (5/13) Feb 01 2021 As long as they are all arrays, yes, the compiler calls a single runtime...
- Steven Schveighoffer (4/9) Feb 01 2021 One of my oldest Enhancement requests:
Given char x[]; why is typeof("a" ~ x) `char[]` when typeof("a" ~ x.idup) is `string`? My case is class NameLookupException : Exception { this(string name) { super("Name " ~ name ~ " could not be found"); } this(scope const(char)[] name) { super("Name " ~ name.idup ~ " could not be found"); } } where I instead would like to only need class NameLookupException : Exception { this(scope const(char)[] name) { super("Name " ~ name ~ " could not be found"); } } Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`? Would class NameLookupException : Exception { this(scope const(char)[] name) trusted { super("Name " ~ cast(string)name ~ " could not be found"); } } be ok?
Jan 31 2021
On Sunday, 31 January 2021 at 21:48:09 UTC, Per Nordlöw wrote:Given char x[]; why is typeof("a" ~ x) `char[]` when typeof("a" ~ x.idup) is `string`? My case is class NameLookupException : Exception { this(string name) { super("Name " ~ name ~ " could not be found"); } this(scope const(char)[] name) { super("Name " ~ name.idup ~ " could not be found"); } } where I instead would like to only need class NameLookupException : Exception { this(scope const(char)[] name) { super("Name " ~ name ~ " could not be found"); } } Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`?Because if you have arrays of reference types, it's possible to change an element of the mutable array, which will affect the immutable array, those breaking the immutability. Example: class Foo { int a; } void main() { Foo[] a = [new Foo]; immutable(Foo)[] b = [new Foo]; // `string` is an alias for `immutable(char)[]` auto c = b ~ a; a[0].a = 3; assert(c[1].a == 3); } Due to language consistency it should behave the same for all types. In the above example, `c` is typed as `const(Foo)[]`. Although, I wonder why in your example the concatenation is typed as `char[]` instead of `const(char)[]`. Perhaps that's a bug. -- /Jacob Carlborg
Feb 01 2021
On Monday, 1 February 2021 at 10:27:29 UTC, Jacob Carlborg wrote:I still don't understand why that restriction applies to arrays of values types (such as `char`). Having this limitation makes my code example more bloated or less efficient memorywise; I either have to define two separate ctors or force an .idup at the site of the exception construction.Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`?Because if you have arrays of reference types, it's possible to change an element of the mutable array, which will affect the immutable array, those breaking the immutability. Example:
Feb 01 2021
On 31.01.21 22:48, Per Nordlöw wrote:Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`?If concatenation is guaranteed to allocate a new array, then it should be "strongly pure", and the conversion should work. I'm not sure if it is guaranteed to allocate a new array.Would class NameLookupException : Exception { this(scope const(char)[] name) trusted { super("Name " ~ cast(string)name ~ " could not be found"); } } be ok?Only if you know for sure that you're dealing with a compiler bug here. As another workaround, you can use std.conv.text: import std.conv: text; super(text("Name ", name, " could not be found"));
Feb 01 2021
On 2/1/21 7:17 AM, ag0aep6g wrote:On 31.01.21 22:48, Per Nordlöw wrote:It is. https://dlang.org/spec/arrays.html#array-concatenation "Concatenation always creates a copy of its operands, even if one of the operands is a 0 length array" -SteveWhy isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`?If concatenation is guaranteed to allocate a new array, then it should be "strongly pure", and the conversion should work. I'm not sure if it is guaranteed to allocate a new array.
Feb 01 2021
On Monday, 1 February 2021 at 15:47:33 UTC, Steven Schveighoffer wrote:"Concatenation always creates a copy of its operands, even if one of the operands is a 0 length array"Btw, does x ~ y ~ z ~ ... result in a single allocation?
Feb 01 2021
On Monday, 1 February 2021 at 16:30:31 UTC, Per Nordlöw wrote:Btw, does x ~ y ~ z ~ ... result in a single allocation?Provided all the operands has a `length` property.
Feb 01 2021
On 2/1/21 11:31 AM, Per Nordlöw wrote:On Monday, 1 February 2021 at 16:30:31 UTC, Per Nordlöw wrote:As long as they are all arrays, yes, the compiler calls a single runtime call to concatenate all of them. For custom types, it's going to do them in order, 2 at a time. -SteveBtw, does x ~ y ~ z ~ ... result in a single allocation?Provided all the operands has a `length` property.
Feb 01 2021
On 1/31/21 4:48 PM, Per Nordlöw wrote:Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`?One of my oldest Enhancement requests: https://issues.dlang.org/show_bug.cgi?id=1654 -Steve
Feb 01 2021