digitalmars.D.learn - Casting non-aliased mutable arrays to immutable in return values
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (18/18) Aug 29 2017 Is it recommended to cast an unaliased array to `immutable` after
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/30) Aug 29 2017 Yes and assumeUnique does exactly that:
- Jonathan M Davis via Digitalmars-d-learn (25/43) Aug 29 2017 It's perfectly legitimate to construct an object as mutable and then cas...
- =?UTF-8?B?Tm9yZGzDtnc=?= (4/8) Aug 29 2017 I'm, as always, grateful for your thorough answers, Jonathan.
Is it recommended to cast an unaliased array to `immutable` after
it has been initialized?
The reason for asking is that I would like the following function
void[] rawReadNullTerminated(string path)
safe
{
import std.stdio : File;
auto file = File(path, `rb`);
import std.array : uninitializedArray;
ubyte[] data = uninitializedArray!(ubyte[])(file.size + 1);
file.rawRead(data);
data[file.size] = 0; // null terminator for sentinel
return data; // TODO can we cast this to
`immutable(void)[]`?
}
to have an immutable return type.
I'm aware of that I need to verify the contexts as UTF-8 if I
want to treat it as text.
Aug 29 2017
On 08/29/2017 09:09 AM, Per Nordlöw wrote:
Is it recommended to cast an unaliased array to `immutable` after it has
been initialized?
The reason for asking is that I would like the following function
void[] rawReadNullTerminated(string path)
safe
{
import std.stdio : File;
auto file = File(path, `rb`);
import std.array : uninitializedArray;
ubyte[] data = uninitializedArray!(ubyte[])(file.size + 1);
file.rawRead(data);
data[file.size] = 0; // null terminator for sentinel
return data; // TODO can we cast this to
`immutable(void)[]`?
}
to have an immutable return type.
I'm aware of that I need to verify the contexts as UTF-8 if I want to
treat it as text.
Yes and assumeUnique does exactly that:
https://dlang.org/library/std/exception/assume_unique.html
Further, if your function is pure, the cast is implicit for the caller:
void[] foo() pure {
return new void[](10);
}
void main() {
void[] a = foo();
immutable(void)[] b = foo(); // works
}
Ali
Aug 29 2017
On Tuesday, August 29, 2017 16:09:17 Per Nordlöw via Digitalmars-d-learn
wrote:
Is it recommended to cast an unaliased array to `immutable` after
it has been initialized?
The reason for asking is that I would like the following function
void[] rawReadNullTerminated(string path)
safe
{
import std.stdio : File;
auto file = File(path, `rb`);
import std.array : uninitializedArray;
ubyte[] data = uninitializedArray!(ubyte[])(file.size + 1);
file.rawRead(data);
data[file.size] = 0; // null terminator for sentinel
return data; // TODO can we cast this to
`immutable(void)[]`?
}
to have an immutable return type.
I'm aware of that I need to verify the contexts as UTF-8 if I
want to treat it as text.
It's perfectly legitimate to construct an object as mutable and then cast it
to immutable if there are no other mutable references to it - that's what
std.exception.assumeUnique is for. It does the cast for you while
documenting your intent. However, the better solution if you can do it is to
create the object in a pure function that returns it. Then, it can be
implicitly converted to immutable so long as the compiler can guarantee that
the return value was not passed to the function. In this particular case,
you'd probably create a pure, nested function that took the File object and
returned the array.
Now, as for immutable(void)[], that seems pretty weird to me. Normally, when
folks use void[], it doesn't have any qualifiers on it. But I don't know
that there's actually a problem using qualifiers on it. Certainly, it
compiles. I'd probably just use immutable(ubyte)[] and not anything with
void, but this is obviously just a snippet of your code, and I have no idea
what the rest of it is doing, so something with void instead of ubyte may
very well be the correct solution. You'll obviously have to be the judge of
that. But pretty much the only time that I'd use any kind of void array
though is when accepting arbitrary arrays of data that is going to be
converted to bytes (e.g. for a socket). I wouldn't pass it around. I don't
know what other folks would do though.
Regardless, using assumeUnique or using a pure function to construct the
object and implicitly convert it to immutable works for types in general.
- Jonathan M Davis
Aug 29 2017
On Tuesday, 29 August 2017 at 16:41:48 UTC, Jonathan M Davis wrote:Regardless, using assumeUnique or using a pure function to construct the object and implicitly convert it to immutable works for types in general. - Jonathan M DavisI'm, as always, grateful for your thorough answers, Jonathan. Thank you.
Aug 29 2017









=?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> 