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

Reply via email to