www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Deprecation: foreach: loop index implicitly converted from size_t to

reply Michael <michael toohuman.io> writes:
Hello all,

I am getting this deprecation warning when compiling using DMD64 
D Compiler v2.084.0 on Linux. I'm a little unsure what the 
problem is, however, because the code producing these warnings 
tends to be of the form:

 foreach (int i, ref prop; props)
This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now? Thanks, Michael.
Jan 18
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote:
 Hello all,

 I am getting this deprecation warning when compiling using 
 DMD64 D Compiler v2.084.0 on Linux. I'm a little unsure what 
 the problem is, however, because the code producing these 
 warnings tends to be of the form:

 foreach (int i, ref prop; props)
This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now? Thanks, Michael.
 foreach (int i, ref prop; props)
All you need to do is
 foreach (i, ref prop; props)
The reason for the deprecation is that if your array props is > 2GB int can't span the range of indices necessary because it will overflow.
Jan 18
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/18/19 7:27 AM, Michael wrote:
 Hello all,
 
 I am getting this deprecation warning when compiling using DMD64 D 
 Compiler v2.084.0 on Linux. I'm a little unsure what the problem is, 
 however, because the code producing these warnings tends to be of the form:
 
 foreach (int i, ref prop; props)
This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now?
That's one possibility. You can avoid to!int by using a mask or a cast: foreach(_i, ref prop; props) { int i = _i & 0xffff_ffff; auto i2 = cast(int)_i; } It's less than ideal, but the reason is that there is a possibility that props could have 2^31 or more elements, in which case int will not cut it. It's forcing you to make that decision that it's OK vs. the compiler making that assumption. Any time the compiler is throwing away data without a cast, D tends to require buy in from the developer. Note that this is much more of a problem with smaller types (short or byte), but it would be inconsistent not to also flag int as problematic. I would recommend just using foreach(i, ref prop; props) and casting only where it's absolutely necessary. -Steve
Jan 18
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote:
 This, to be, looks like quite the explicit conversion, no?
Yeah, I agree. But the language is silly. I just leave the type out of foreach and explicitly cast it inside the body.
Jan 18
parent reply Michael <michael toohuman.io> writes:
On Friday, 18 January 2019 at 13:29:29 UTC, Adam D. Ruppe wrote:
 On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote:
 This, to be, looks like quite the explicit conversion, no?
Yeah, I agree. But the language is silly. I just leave the type out of foreach and explicitly cast it inside the body.
Thank you all for the concise explanations and suggestions, I think that's fairly straightforward. I thought perhaps I was doing the sensible thing of dealing with the conversion inside the foreach statement, but I guess not!
Jan 18
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, January 18, 2019 8:34:22 AM MST Michael via Digitalmars-d-learn 
wrote:
 On Friday, 18 January 2019 at 13:29:29 UTC, Adam D. Ruppe wrote:
 On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote:
 This, to be, looks like quite the explicit conversion, no?
Yeah, I agree. But the language is silly. I just leave the type out of foreach and explicitly cast it inside the body.
Thank you all for the concise explanations and suggestions, I think that's fairly straightforward. I thought perhaps I was doing the sensible thing of dealing with the conversion inside the foreach statement, but I guess not!
Well, you were really doing the equivalent of simply declaring a variable without a cast. e.g. int i = arr.length; rather than int i = cast(int)arr.length; In general, if the compiler treated giving the foreach variable an explicit type as being a cast, it would make it really easy to screw up and unknowingly give a different type than the actual type of the values and end up with an invisible cast, which could cause subtle bugs. IIRC, the only case where foreach treats giving an explict type as anything like a cast is when you're iterating over a string type, and you give a character type different from the character type of the string. In that case, it actually decodes the string from one Unicode encoding and encodes it in the other. Whether the language should have done that rather than requiring that a library solution be used is debatable (I believe that it far predates Phobos having the Unicode handling that it does now), but at least it can't result in stuff like silent truncation. Worst case, it has a silent performance hit, or you get an unexpected UnicodeException at runtime due to invalid Unicode. - Jonathan M Davis
Jan 18