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