On 07/10/2013 03:08 PM, bearophile wrote:
> Do you know why the assignment to 'item' is accepted in the first case
> and refused in the second?
>
>
> ubyte generate1(s...)() {
> ubyte[10] result;
> foreach (immutable i, ref item; result)
> item = s[0][0] << 4;
s[0][0] is known to be int 1 at compile time. It is also known that (1
<< 4) can fit in a ubyte by value range propagation. dmd is being helpful.
Change the code so that the result does not fit a ubyte you will get the
same error as in line 11.
a) Shift by 8 instead of 4
b) Change the value in main to something like 42
> return result[0];
> }
>
> ubyte generate2(s...)() {
> ubyte[10] result;
> foreach (immutable i, ref item; result)
> item = s[0][i % 3] << 4; // line 11
That foreach is a runtime foreach because it is applied on 'result' as
opposed to the type tuple 's'. Apparently the compiler does not do that
kind of code analysis.
> return result[0];
> }
>
> void main() {
> enum ubyte[16] data = [1, 2, 3, 4];
> auto g1 = generate1!data;
> auto g2 = generate2!data;
> }
>
>
> dmd gives:
>
> test.d(11): Error: cannot implicitly convert expression
> (cast(int)[cast(ubyte)1u, cast(ubyte)2u, cast(ubyte)3u, cast(ubyte)4u,
> cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u,
> cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u,
> cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u][i % 3u] <<
> 4) of type int to ubyte
>
>
> Bye and thank you,
> bearophile
Ali