Bug 3652 – Allow explicit and implicit casting of dynamic array slices of known size to static array
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2009-12-26T14:17:17Z
Last change time
2020-05-15T16:11:38Z
Keywords
pull
Assigned to
No Owner
Creator
Witold Baryluk
Comments
Comment #0 by witold.baryluk+d — 2009-12-26T14:17:17Z
Consider this:
void foo(float[4] x) {
return x[0]+x[1]*x[2]-x[3];
}
void main() {
float[] xs = read_floats_from_file();
foreach (i; 0 .. xs.length-4) {
foo(xs[ i .. i+4]);
}
}
or simpler thing to calculate in compile time:
void main() {
float[] xs = read_floats_from_file();
foo(xs[ 0 .. 4]);
}
In both cases compiler will say:
cannot implicitly convert expression (_adDupT((& _D11TypeInfo_Af6__initZ),qs[0u..4u])) of type float[] to float[4u]
or something similar. It is hard to see why this is really needed.
How about allowing (and performing) implicit cast to static array if compiler knows (or can easly infere) size of the slice and it aggree with target type? Of course there will be situations where we have no knowledge about it:
void main() {
float[] xs = read_floats_from_file();
uint a = rand() % xs.length;
foo(xs[ 0 .. a ]);
}
But allowing implicit cast also can detect other errors:
foreach (i; 0 .. xs.length-4) {
foo(xs[ i .. i+3]);
}
Compiler in such situation will complain not because we are using float[] to float[4] conversion, but because we are trying to call float[4] function using float[3] slice.
Comment #1 by witold.baryluk+d — 2009-12-26T14:18:34Z
So essentially problem is that slices are just dynamic arrays. So bringing back the topic of making slices different/distinctive types.
Comment #2 by witold.baryluk+d — 2009-12-26T14:21:40Z
It is even worse that i was innitially thinking:
explicit casting doesn't work:
series2.d(113): Error: e2ir: cannot cast qs[0u..1u] of type float[] to type float[1u]
Comment #3 by k.hara.pg — 2013-03-01T02:30:36Z
Partial implementation:
https://github.com/D-Programming-Language/dmd/pull/1705
(In reply to comment #0)
> float[] xs = read_floats_from_file();
> foreach (i; 0 .. xs.length-4) {
> foo(xs[i .. i+4]);
> }
In this case, detecting length == 4 in compile time is difficult with complicated cases. Consider:
foo(xs[(i*4+10)/2 .. (i*8>>1)/2+9]);
// lwr = (i*4 + 10)/2 = i*4/2 + 10/2 = (i*2+5)
// upr = (i*8>>1)/2 + 5 = (i*4/2) + 5 = i*2 + 9 = (i*2+5) + 4
So this is not supported in my pull request.
Comment #4 by github-bugzilla — 2013-03-02T11:12:56Z
Comment #5 by bearophile_hugs — 2013-03-02T12:00:57Z
(In reply to comment #3)
> So this is not supported in my pull request.
Your pull request is not perfect, but it's a significant improvement.
Maybe related: Issue 8277 and Issue 9165
Comment #6 by yebblies — 2013-07-27T23:37:52Z
*** Issue 8843 has been marked as a duplicate of this issue. ***
Comment #7 by k.hara.pg — 2014-12-10T09:19:46Z
See also: issue 13700
Comment #8 by github-bugzilla — 2015-01-01T12:53:40Z
Comment #9 by witold.baryluk+d — 2020-05-15T16:11:38Z
It does appear way better indeed.
https://godbolt.org/z/taxeAR
One way to emulate, the foo(xs[i .. i+4]), is by doing foo(xs[i .. i+4][0 .. 4]).
It is hard to support arbitrary expression. Not only it would be very hard to write specification to indicate what kind of expressions are supported by compiler.
in general function equality is equivalent to halting problem, so only some poorly defined subset (by algorithm) can be supported. compiler is not full symbolic algebra system, so it is probably not worth implementing or specifying.
Thanks for the patches, Kenji.