A range analysis question

Ali Çehreli acehreli at yahoo.com
Wed Jul 10 15:58:43 PDT 2013


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



More information about the Digitalmars-d-learn mailing list