www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Signed-unsigned comparisons in Phobos

reply bearophile <bearophileHUGS lycos.com> writes:
I have added this bit of code to my dmd, it gives warnings in cases of integral
signed-unsigned comparisons:
https://github.com/D-Programming-Language/dmd/pull/119

Then I have compiled Phobos (with unittests) with the -wi switch, this has
generated some of those signed-unsigned warning messages, maybe this list is of
interest for someone:
http://codepad.org/Ku42j1SR

Note: that "ignored variadic arguments to the constructor" that lists no line
number is generated at line 1766 of template ConstructorGeneratingPolicy()
inside typecons.d Phobos module.

Bye,
bearophile
Aug 11 2011
parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 I have added this bit of code to my dmd, it gives warnings in cases of
integral signed-unsigned comparisons:
 https://github.com/D-Programming-Language/dmd/pull/119
 
 Then I have compiled Phobos (with unittests) with the -wi switch, this has
generated some of those signed-unsigned warning messages, maybe this list is of
interest for someone:
 http://codepad.org/Ku42j1SR
 
 Note: that "ignored variadic arguments to the constructor" that lists no line
number is generated at line 1766 of template ConstructorGeneratingPolicy()
inside typecons.d Phobos module.
 
 Bye,
 bearophile

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
Aug 12 2011
next sibling parent reply kennytm <kennytm gmail.com> writes:
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.
Aug 12 2011
next sibling parent reply Don <nospam nospam.com> writes:
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?

 And the type of index 'i' should be 'size_t' anyway.

Why? It will only ever be in the range 0..6.
Aug 12 2011
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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.
Aug 12 2011
parent reply Jacob Carlborg <doob me.com> writes:
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
Aug 12 2011
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/12/2011 08:32 PM, Jacob Carlborg wrote:
 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?

Probably because of this: for(unsigned int i=0;i<n;i++){} // ok for(unsigned int i=n-1;i>=0;i--){} // bam!
Aug 12 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/12/2011 11:32 AM, Jacob Carlborg wrote:
 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?

1. size_t didn't exist 2. sizeof(int) == sizeof(pointer) pretty much everywhere 3. Signed indices meant you could index backwards 4. K+R used 'int' as an index everywhere
Aug 12 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-08-13 00:08, Walter Bright wrote:
 On 8/12/2011 11:32 AM, Jacob Carlborg wrote:
 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?

1. size_t didn't exist 2. sizeof(int) == sizeof(pointer) pretty much everywhere 3. Signed indices meant you could index backwards 4. K+R used 'int' as an index everywhere

Ok, I see, thanks for the reply. -- /Jacob Carlborg
Aug 13 2011
prev sibling parent Don <nospam nospam.com> writes:
Jonathan M Davis wrote:
 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


 And the type of index 'i' should be 'size_t' anyway.


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.

But it will have signedness problems if you try to use it any expression that involves a subtraction. Basically, unsigned types are poisonous, and for modern systems, size_t should have been an signed type. It's very unfortunate. 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.

You actually have fewer bugs if you use int, _provided_ that you can guarantee that the length can't be greater than int.max. (Of course, you can't generally guarantee that; hence your recommendation is a good one).
Aug 12 2011
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-08-12 14:55, Marco Leise 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've done something similar myself. -- /Jacob Carlborg
Aug 12 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
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
Aug 12 2011
prev sibling next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
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; ) {...}
Aug 12 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
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
Aug 12 2011
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/12/2011 03:08 PM, bearophile wrote:
 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

But some people seem to strongly dislike it though. It is a bit unfortunate that you don't currently get the same functionality by using retro.
Aug 12 2011
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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--;
Aug 12 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
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
Aug 12 2011
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/12/2011 09:32 PM, bearophile wrote:
 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

That is because it is not a comma operator. It is an argument list. ;) array[(i, j)] = 5; works fine.
Aug 12 2011
parent reply Don <nospam nospam.com> writes:
Timon Gehr wrote:
 On 08/12/2011 09:32 PM, bearophile wrote:
 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

That is because it is not a comma operator. It is an argument list. ;) array[(i, j)] = 5; works fine.

No, it was specifically disallowed. Version D 2.037 Dec 3, 2009 New/Changed Features No more comma operators allowed between [ ].
Aug 12 2011
next sibling parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 08/12/2011 04:06 PM, Don wrote:
 No, it was specifically disallowed.

 Version D 2.037 Dec 3, 2009
 New/Changed Features
 No more comma operators allowed between [ ].

I think that was for type declarations, not index expressions. you can still do this: import std.stdio; struct X{ void opIndex(int i, int j){ writeln(i, " ", j); } } void main() { X x; x[1,2]; }
Aug 12 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/13/2011 12:37 AM, Ellery Newcomer wrote:
 On 08/12/2011 04:06 PM, Don wrote:
 No, it was specifically disallowed.

 Version D 2.037 Dec 3, 2009
 New/Changed Features
 No more comma operators allowed between [ ].

I think that was for type declarations, not index expressions. you can still do this: import std.stdio; struct X{ void opIndex(int i, int j){ writeln(i, " ", j); } } void main() { X x; x[1,2]; }

Ah ok, I did not see this post before. This makes everything clear. Thanks!
Aug 12 2011
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/12/2011 11:06 PM, Don wrote:
 Timon Gehr wrote:
 On 08/12/2011 09:32 PM, bearophile wrote:
 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

That is because it is not a comma operator. It is an argument list. ;) array[(i, j)] = 5; works fine.

No, it was specifically disallowed. Version D 2.037 Dec 3, 2009 New/Changed Features No more comma operators allowed between [ ].

Interesting. So first , inside [ ] was specifically special cased to be a comma operator when indexing into an array (you can overload indexing to take more than one argument) and now those are disallowed? Quite messy. Imho that is just an implementation detail and does not invalidate my statement. (in case you were actually saying that the code should not compile, it does.)
Aug 12 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
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'.
Aug 12 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
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; ... }
Aug 12 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
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!
Aug 12 2011
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Aug 12 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Aug 12 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
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.
Aug 12 2011
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Aug 12 2011
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Fri, 12 Aug 2011 20:36:32 +0200, Jacob Carlborg <doob me.com> wrote:

 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 }

If D had only UFCS of the two, we could do this: foreach (i; 0.iota(9)) { // stuffs } foreach (i; 9.iota(0,-1)) { // stuffs } But yeah, the delegate syntax would also be very nice. I'm not so sure this is its killer use, though. :p -- Simen
Aug 12 2011