August 12, 2011
Am 12.08.2011, 14:55 Uhr, schrieb Marco Leise <Marco.Leise@gmx.de>:

> for (size_t i = x.length; i-- > 0; ) {...}

Actually this is probably better:

for (auto i = x.length; i > 0; )
{
    --i;
    ...
}
August 12, 2011
Am 12.08.2011, 15:44 Uhr, schrieb Timon Gehr <timon.gehr@gmx.ch>:

> On 08/12/2011 03:33 PM, Marco Leise wrote:
>> Am 12.08.2011, 15:08 Uhr, schrieb bearophile <bearophileHUGS@lycos.com>:
>>
>>> Marco Leise:
>>>
>>>> Just remember that reverse loops are written like this:
>>>>
>>>> for (size_t i = x.length; i-- > 0; ) {...}
>>>
>>> Thankfully in D there is foreach_reverse :-)
>>>
>>> import std.stdio;
>>>
>>> void main() {
>>> auto array = [10, 20, 30];
>>>
>>> for (size_t i = array.length; i-- > 0; )
>>> writeln(i, " ", array[i]);
>>>
>>> foreach_reverse (i, item; array)
>>> writeln(i, " ", item);
>>> }
>>>
>>> Bye,
>>> bearophile
>>
>> Sure, but we were talking about for, not foreach. Maybe these cases in
>> Phobos cannot use foreach, because they modify 'i' or they don't require
>> 'item'.
>
> foreach_reverse(i;0..array.length) writeln(array[i]),i--;

:D it doesn't crash! Thx, I'll ditch the C syntax from now on!
August 12, 2011
On Fri, 12 Aug 2011 14:55:26 +0200, Marco Leise <Marco.Leise@gmx.de> wrote:

> Am 12.08.2011, 12:22 Uhr, schrieb kennytm <kennytm@gmail.com>:
>
>> Don <nospam@nospam.com> wrote:
>>
>>> I've had a look at a dozen or so of these, and they were all real. I
>>> didn't see any which require a cast to "make the compiler shut up".
>>> That's pretty impressive. In C++ I find that such messages are nearly
>>> always false positives.
>>>
>>> The one case where it's a bit annoying is this:
>>>
>>> int [] x = new int[6]; // or x = some array literal.
>>> for (int i = 0; i < x.length; ++i) {...}
>>>
>>> Here is a suggestion for how we could eliminate such false positives.
>>> http://d.puremagic.com/issues/show_bug.cgi?id=6478
>>
>> Doesn't this require flow analysis? And the type of index 'i' should be
>> 'size_t' anyway.
>
> I think I once shot myself in the foot with this when I used 'auto' for 'i' and the code wouldn't compile on x86_64, because I assigned the variable to an int or uint later on in the loop. You just have to be aware that this is an unsigned integer of machine word length. So I agree with kennytm on this.
>
> Just remember that reverse loops are written like this:
>
> for (size_t i = x.length; i-- > 0; ) {...}

I like using the long arrow operator for this:
  i --> 0 // i goes to 0

-- 
  Simen
August 12, 2011
On Friday, August 12, 2011 12:39:01 Don wrote:
> kennytm wrote:
> > Don <nospam@nospam.com> wrote:
> >> I've had a look at a dozen or so of these, and they were all real. I didn't see any which require a cast to "make the compiler shut up". That's pretty impressive. In C++ I find that such messages are nearly always false positives.
> >> 
> >> The one case where it's a bit annoying is this:
> >> 
> >> int [] x = new int[6]; // or x = some array literal.
> >> for (int i = 0; i < x.length; ++i) {...}
> >> 
> >> Here is a suggestion for how we could eliminate such false positives. http://d.puremagic.com/issues/show_bug.cgi?id=6478
> > 
> > Doesn't this require flow analysis?
> 
> Yes. See the bug report.
> 
> > And the type of index 'i' should be 'size_t' anyway.
> 
> Why? It will only ever be in the range 0..6.

Sure. it works in this case, but in the general case it's good practice to use size_t for indices, because that's the actual type of the index, so it won't have signedness or range problems. Unfortunately, it's a practice that many people don't seem to follow (in both C/C++ and D), since it's so natural to use int (or auto in D), but I'd definitely argue that programmers should normally be using size_t for indices.

- Jonathan M Davis
August 12, 2011
Am 12.08.2011, 17:48 Uhr, schrieb Simen Kjaeraas <simen.kjaras@gmail.com>:

> On Fri, 12 Aug 2011 14:55:26 +0200, Marco Leise <Marco.Leise@gmx.de> wrote:
>
>> Am 12.08.2011, 12:22 Uhr, schrieb kennytm <kennytm@gmail.com>:
>>
>>> Don <nospam@nospam.com> wrote:
>>>
>>>> I've had a look at a dozen or so of these, and they were all real. I
>>>> didn't see any which require a cast to "make the compiler shut up".
>>>> That's pretty impressive. In C++ I find that such messages are nearly
>>>> always false positives.
>>>>
>>>> The one case where it's a bit annoying is this:
>>>>
>>>> int [] x = new int[6]; // or x = some array literal.
>>>> for (int i = 0; i < x.length; ++i) {...}
>>>>
>>>> Here is a suggestion for how we could eliminate such false positives.
>>>> http://d.puremagic.com/issues/show_bug.cgi?id=6478
>>>
>>> Doesn't this require flow analysis? And the type of index 'i' should be
>>> 'size_t' anyway.
>>
>> I think I once shot myself in the foot with this when I used 'auto' for 'i' and the code wouldn't compile on x86_64, because I assigned the variable to an int or uint later on in the loop. You just have to be aware that this is an unsigned integer of machine word length. So I agree with kennytm on this.
>>
>> Just remember that reverse loops are written like this:
>>
>> for (size_t i = x.length; i-- > 0; ) {...}
>
> I like using the long arrow operator for this:
>    i --> 0 // i goes to 0

This way it is actually fun to cripple the for loop, yay. Still if people started to argue that it is a bad idea to modify variables in the condition I'd silently agree. So a look at "foreach_reverse (i; 0..x.length) {...}" might be worth it. I guess after a while I will get used to it. It even reminds me of the Pascal "for"-syntax a bit, which is "for i := 0 to 9 do ...". It has no receipt for the reverse zero-length array loop though as far as I know.
August 12, 2011
On 8/12/2011 8:52 AM, Jonathan M Davis wrote:
> it's a practice that many
> people don't seem to follow (in both C/C++ and D), since it's so natural to
> use int (or auto in D),

Back in the olden days of C, it was "best practice" to use int as an index. Times have changed, but old habits die hard.
August 12, 2011
On Fri, 12 Aug 2011 19:19:09 +0200, Marco Leise <Marco.Leise@gmx.de> wrote:

> Am 12.08.2011, 17:48 Uhr, schrieb Simen Kjaeraas <simen.kjaras@gmail.com>:
>
>> On Fri, 12 Aug 2011 14:55:26 +0200, Marco Leise <Marco.Leise@gmx.de> wrote:
>>
>>> Am 12.08.2011, 12:22 Uhr, schrieb kennytm <kennytm@gmail.com>:
>>>
>>>> Don <nospam@nospam.com> wrote:
>>>>
>>>>> I've had a look at a dozen or so of these, and they were all real. I
>>>>> didn't see any which require a cast to "make the compiler shut up".
>>>>> That's pretty impressive. In C++ I find that such messages are nearly
>>>>> always false positives.
>>>>>
>>>>> The one case where it's a bit annoying is this:
>>>>>
>>>>> int [] x = new int[6]; // or x = some array literal.
>>>>> for (int i = 0; i < x.length; ++i) {...}
>>>>>
>>>>> Here is a suggestion for how we could eliminate such false positives.
>>>>> http://d.puremagic.com/issues/show_bug.cgi?id=6478
>>>>
>>>> Doesn't this require flow analysis? And the type of index 'i' should be
>>>> 'size_t' anyway.
>>>
>>> I think I once shot myself in the foot with this when I used 'auto' for 'i' and the code wouldn't compile on x86_64, because I assigned the variable to an int or uint later on in the loop. You just have to be aware that this is an unsigned integer of machine word length. So I agree with kennytm on this.
>>>
>>> Just remember that reverse loops are written like this:
>>>
>>> for (size_t i = x.length; i-- > 0; ) {...}
>>
>> I like using the long arrow operator for this:
>>    i --> 0 // i goes to 0
>
> This way it is actually fun to cripple the for loop, yay. Still if people started to argue that it is a bad idea to modify variables in the condition I'd silently agree. So a look at "foreach_reverse (i; 0..x.length) {...}" might be worth it. I guess after a while I will get used to it. It even reminds me of the Pascal "for"-syntax a bit, which is "for i := 0 to 9 do ...". It has no receipt for the reverse zero-length array loop though as far as I know.

Pascal has downto:

for i := 9 downto 0 do ...

-- 
  Simen
August 12, 2011
On 2011-08-12 20:16, Walter Bright wrote:
> On 8/12/2011 8:52 AM, Jonathan M Davis wrote:
>> it's a practice that many
>> people don't seem to follow (in both C/C++ and D), since it's so
>> natural to
>> use int (or auto in D),
>
> Back in the olden days of C, it was "best practice" to use int as an
> index. Times have changed, but old habits die hard.

Just out of curiosity, why was that?

-- 
/Jacob Carlborg
August 12, 2011
On 2011-08-12 20:26, Simen Kjaeraas wrote:
> On Fri, 12 Aug 2011 19:19:09 +0200, Marco Leise <Marco.Leise@gmx.de> wrote:
>> This way it is actually fun to cripple the for loop, yay. Still if
>> people started to argue that it is a bad idea to modify variables in
>> the condition I'd silently agree. So a look at "foreach_reverse (i;
>> 0..x.length) {...}" might be worth it. I guess after a while I will
>> get used to it. It even reminds me of the Pascal "for"-syntax a bit,
>> which is "for i := 0 to 9 do ...". It has no receipt for the reverse
>> zero-length array loop though as far as I know.
>
> Pascal has downto:
>
> for i := 9 downto 0 do ...

If D had uniform function call syntax and good looking delegate literals we could do this:

0.upto(9 ; i) {
    // do something with i
}

9.downto(0 ; i) {
    // do something with i
}

-- 
/Jacob Carlborg
August 12, 2011
Timon Gehr:

> foreach_reverse(i;0..array.length) writeln(array[i]),i--;

I'd like to statically forbid some more usages of the comma operator in D :-)

Some of them are already forbidden compared to C. This is valid C code:

int main() {
    int array[5];
    int i = 1;
    int j = 2;
    array[i, j] = 5;
    return 0;
}

While in D it's forbidden, it catches a possible wrong usage: Line 5: Error: only one index allowed to index int[5u]

Bye,
bearophile