August 12, 2011
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
>>> 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. 

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).

August 12, 2011
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!
August 12, 2011
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.
August 12, 2011
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 [ ].
August 12, 2011
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
August 12, 2011
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];
}
August 12, 2011
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
August 12, 2011
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.)

August 12, 2011
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!
August 13, 2011
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
1 2 3
Next ›   Last »