char[] annoyance...
Georg Wrede
georg.wrede at nospam.org
Mon Apr 10 07:42:33 PDT 2006
Regan Heath wrote:
> On Mon, 10 Apr 2006 11:58:09 +1000, Derek Parnell <derek at psych.ward> wrote:
>
>> On Mon, 10 Apr 2006 12:23:06 +1200, Regan Heath wrote:
>>
>>> Take this code:
>>>
>>> void main()
>>> {
>>> //..open a file, read line for line, on each line:
>>>
>>> for(int i = 0; i < line.length-2; i++) {
>>> if (line[i..i+2] != "||") continue;
>>> //..etc..
>>> }
>>> }
>>>
>>> There is a subtle bug. On all lines with a length of 0 or 1 it will give
>>> the following error:
>>>
>>> Error: ArrayBoundsError line_length.d(6)
>>>
>>> The problem is of course the statement "i < line.length-2".
>>> line.length is
>>> unsigned, and when you - 2 from an unsigned value.. well lets just say
>>> that it's bigger than the actual length of the line - 2.
>>>
>>> Of course there are plently of other ways to code this, perhaps using
>>> foreach, but that's not the point. The point is that this code _can_ be
>>> written and on the surface looks fine. Not even -w (warnings) spots the
>>> signed/unsigned problem. At the very least can we get a warning for
>>> this?
>>
>>
>> I too have tripped up on this 'bug' and it is very annoying and
>> surprising.
>>
>> However your approach to the problem might need to change...as you
>> state -
>> "On all lines with a length of 0 or 1 it will give the following
>> error..."
>> - and this is because the test that you are performing is only applicable
>> to lines with two or more characters in them ... so make that condition a
>> part of the algorithm ...
>>
>> if (line.length >= 2) {
>> for(int i = 0; i < line.length-2; i++) {
>> if (line[i..i+2] != "||") continue;
>> //..etc..
>> }
>> }
>> else {
>> // do something for short lines...
>> }
>
>
> Thanks Derek, that's exactly what I did.
>
> The point of this post isn't to get help with one specific problem but
> rather to ask whether there is a solution to the underlying problem
> behaviour. I suspect this behaviour will be the source of many bugs to
> come and I wonder if there is a way to avoid them.
First, how come you don't use this code?
for (int i=0; i<line.length-2; i++)
{
if (line[i..i] == "|")
if (line[i+1..i+1] == "|")
continue;
}
It should be more than twice as fast.
Second, isn't your code just an excellent example of why we have bounds
checking in D in the first place?
I think the obvious and clear-for-the-reader solution is to wrap that
code in an if:
if (line.length > 1)
{
// the above code here
}
I can't see what would be wrong with that.
More information about the Digitalmars-d
mailing list