Bug 9165 – Auto conversion from dynamic array to fixed size array at return

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-12-16T17:16:13Z
Last change time
2024-12-13T18:03:24Z
Assigned to
No Owner
Creator
bearophile_hugs
Moved to GitHub: dmd#18505 →

Comments

Comment #0 by bearophile_hugs — 2012-12-16T17:16:13Z
int[2] foo() { return [1, 2].dup; } int[2] bar() { int[2] __aux = [1, 2].dup; return __aux; } void main() {} DMD 2.061alpha gives: test.d(2): Error: cannot implicitly convert expression (_adDupT(& D11TypeInfo_Ai6__initZ, [1, 2])) of type int[] to int[2u] If possible I'd like to write code as in foo() instead of using a temporary fixed sized array as in bar(). I presume in foo() the data needs to be copied to the stack any way, so probably foo() should just be syntax sugar for bar(). The same problem happens for std.array.array(): int[2] spam() { return [1, 2].array(); } But it doesn't happen for an array literal: int[2] baz() { return [1, 2]; }
Comment #1 by Marco.Leise — 2015-11-23T16:37:03Z
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.
Comment #2 by nick — 2016-04-07T11:09:19Z
This pull at least allows it to be done non-automatically from any range: int[5] = only(1,2,3,4,5).staticArray!5; https://github.com/D-Programming-Language/phobos/pull/4090
Comment #3 by robert.schadek — 2024-12-13T18:03:24Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18505 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB