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









Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> 