foreach counter now must be size_t ?

Rubn where at is.this
Tue Feb 5 21:14:17 UTC 2019


On Tuesday, 5 February 2019 at 04:53:00 UTC, Walter Bright wrote:
> On 2/4/2019 7:15 PM, Timon Gehr wrote:
>> I wish it wasn't. It seems this doesn't do anything useful. If 
>> I'm going through the trouble of explicitly specifying the 
>> counter type to be what I need, why annoy me with this error 
>> message?
>
> It is the same thing as:
>
>     long l;
>     uint i = l; // error
>
> D doesn't allow implicit narrowing conversions that lose 
> information.
>
> If the foreach was written like this:
>
>     void foo(int[3] arr) {
>       foreach (uint i, ref elem; arr) { }
>     }
>
> I.e. where the array bounds are known at compile time, then it 
> works, because:
>
>     enum long l = 3;
>     uint i = l;
>
> also works.


WHAT. WHAT. Where do you see an assignment from size_t to int 
here?

int[] arr = someRandomArray();
for( int i = 0; i < arr.length; ++i ) {
    dg( i, arr[i] );
}

???

There is only a comparison between `int` and `size_t` which is 
completely valid. And as far as I remember you strictly 
disapprove of even allowing a warning to be displayed in that 
case.

> As for "who would ever have an array that big":
>
> 1. It's irrelevant, as the semantics of the language have to be 
> sound across the uses it supports.

If by semantics you are referring to the above, then see the 
above.

Otherwise your misguided attempt to try and illustrate that a 
size_t can't be assigned to an int. Foreach is a special case.

foreach(i, ref int v; someArray) {
    // i is size_t
}

Can you do the following?

     i = 10;

No you can't, cause they aren't the same thing!

If you want to stick with that, I can do a case without creating 
another variable. How do I do that with foreach so I don't have 
to do this:

foreach( i, ref int value; arr ) {
     int i = cast(int)i;
}

foreach( int i, ref int value; arr ) {
     // better
}

> 2. I noticed with Windows MovieMaker that it produces corrupt 
> output files if the movie is bigger than 4Gb. Evidently a 32 
> bit counter isn't enough.

1. That's not even remotely related. The error in Movie Maker is 
caused by the C api (on Windows) uses 32-bit integers.

2. If they were using D and for some reason they wanted to create 
the entire file in memory first before writing it to a file. 
There still would have been the same problem. If you build on 
32-bit size_t is int, so they would be limited to 4 GB files. Not 
to mention how horrible it would be on memory, but I know you and 
DMD love your memory leaks (never running the garbage collector 
nor freeing the memory used) and not distributing 64-bit 
binaries, but I'll leave it at that maybe you would fill an 
entire array before writing it to a file.

3. Creating such a huge array in the first place is just a bad 
idea. You get incompatibilities with 32-bit and 64-bit, and most 
of the time you don't need to do it. It's a code smell honestly. 
You should probably have a structure that specifically deals with 
gigantic arrays, to disable things like copying the array. Though 
again you'll almost never need it except for very special cases.

4. I never said to NEVER use a 64-bit integer, merely that you 
almost never need an array that would fill a 32-bit length (your 
Movie Maker example has not disproved that). Hell you can make 
DMD use 32-bit integers for all it's arrays and it will still 
function even though it runs out of memory (not because it 
allocates an array that fills 32-bit counter though) because it 
is one gigantic memory leak. I know it still works with 32-bit 
cause there is no 64-bit version for Windows! Classic.


More information about the Digitalmars-d mailing list