[Issue 9165] Auto conversion from dynamic array to fixed size array at return
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Mon Nov 23 08:37:03 PST 2015
https://issues.dlang.org/show_bug.cgi?id=9165
Marco Leise <Marco.Leise at gmx.de> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |Marco.Leise at gmx.de
--- Comment #1 from Marco Leise <Marco.Leise at gmx.de> ---
This is more or less actual code of a "packet" with a header and N items. "foo"
returns a reference to the data portion of the n-th item or in other words 14
bytes starting at "offset":
struct S
{
ubyte[100] m_data;
ref inout(ubyte[14]) foo(uint n) inout
{
uint offset = 2 + 14 * n;
// Not accepted:
return m_data[offset .. offset + 14];
}
}
Since D's slice syntax is [start .. stop] we end up converting the information
(offset, length) to (offset, offset+length) which is possibly harder for the
compiler to see through and realize the fixed length of 14 above. The most
idiomatic way I came up with is:
return (cast(inout(ubyte[14][7])) m_data[2 .. 2 + 7 *
(ubyte[14]).sizeof])[n];
This also works when returning structs of size N instead of ubyte[N]. That's
nice when the items are representable as POD structs. Here is an example:
return (cast(inout(Pack[1])) m_data[3 .. 3 + Pack.sizeof])[0];
Note the need to use a static array of length 1 as an intermediate type before
returning. The semantics of casting slices to something else should be made
more consistent. As long as the compiler can deduce a static length they should
implicitly cast to a static array of same type and size and ubyte[]/void[]
should be explicitly castable to structs with the same rules as elsewhere (e.g.
unions) in regards to pointers. I.e. The structs may not contain pointers,
which is fine for data loaded from disk or received over the network.
--
More information about the Digitalmars-d-bugs
mailing list