Array initialization quiz

Xinok xinok at live.com
Wed Nov 30 10:17:34 PST 2011


On 11/30/2011 11:46 AM, Steven Schveighoffer wrote:
> On Wed, 30 Nov 2011 10:54:11 -0500, Xinok <xinok at live.com> wrote:
>
>> On 11/30/2011 7:50 AM, Steven Schveighoffer wrote:
>>> On Tue, 29 Nov 2011 15:06:11 -0500, Jonathan M Davis
>>> <jmdavisProg at gmx.com> wrote:
>>>
>>> The type of the index should be irrelavent to the underlying loop
>>> mechanism.
>>>
>>> Note that the issue is really that foreach(T i, val; arr) {...}
>>> translates to for(T i = 0; i < arr.length; ++i) {auto val = arr[i]; ...}
>>>
>>> Why can't it be (aside from the limitation in for-loop syntax, but you
>>> get the idea): for(size_t _i = 0, T i = _i; _i < arr.length; i = ++_i)
>>> {auto val = arr[_i]; ...}
>>>
>>> Same issue with foreach(i; -10..10), what if I wanted to do foreach
>>> (ubyte i; ubyte.min..ubyte.max + 1). This should not result in an
>>> infinite loop, I should be able to use foreach to iterate all the values
>>> of ubyte. The compiler should just "figure out" how to do it right.
>>>
>>> -Steve
>>
>> This actually doesn't compile:
>> foreach (ubyte i; ubyte.min..ubyte.max + 1)
>> Error: cannot implicitly convert expression (256) of type int to ubyte
>>
>> It's a little more to type, but just write a property which does an
>> explicit cast:
>>
>> foreach(_i; ubyte.min .. ubyte.max + 1){
>> ubyte i(){ return cast(ubyte)_i; }
>> }
>
> This is hugely inefficient...
>
> foreach(_i; ubyte.min..ubyte.max + 1){
> ubyte i = cast(ubyte)_i;
> }
>
> But my point was, foreach over a range gives me all the elements in a
> range, regardless of how the underlying loop is constructed. The
> limitation by the compiler is artificial.
>
> I remember at one point there was someone who had actual code that
> resulted in a loop for ubytes, or was trying to figure out how to
> foreach over all possible ubyte values.
>
> -Steve

It shouldn't be. The compiler should be smart enough to inline the 
function and optimize the typecast to something like this:

void main(string[] args){
	foreach(_i; ubyte.min .. ubyte.max + 1)
		writeln(*cast(ubyte*)&_i);
}

This would actually be faster since you don't have to iterate two variables.


More information about the Digitalmars-d-learn mailing list