Thread overview
Possible bug in skipOver() from std/algorithm/searching.d
Jan 22, 2017
Danny Arends
Jan 22, 2017
Daniel N
Jan 22, 2017
Danny Arends
Jan 22, 2017
Stefan Koch
Jan 22, 2017
Danny Arends
Jan 22, 2017
Stefan Koch
Jan 24, 2017
Bauss
Jan 22, 2017
Chris Wright
January 22, 2017
Hey all,

I encountered some unexpected behavior in std.format, I was parsing Wavefront obj file, and ran into an issue. I updated the compiler to the latest stable version (// DMD64 D Compiler v2.072.2), however I think it's a Phobos related issue.

Given the following code:

---- test.d ----

import std.stdio, std.algorithm, std.conv, std.format, std.string;

void main() {
  int x;
  for (auto t = 40; t < 50; t++) {
    // Create a string holding a number and put a forward slash behind it
    string l = to!string(t) ~ "/";

    // Write the created string to the ouput
    writef("'%s'", l);

    // Read the number using the formattedRead function
    formattedRead(l, "%d", &x);

    // Write the number to the ouput
    writef(" -> '%d'", x);

    // Skip over the loaded number
    l.skipOver(x);

    // Print what is left of the string
    writeln(" -> '", l, "'");
  }
}
-------------------

After running this code  dmd -run test.d
I get the following output:

'40/' -> '40' -> '/'
'41/' -> '41' -> '/'
'42/' -> '42' -> '/'
'43/' -> '43' -> '/'
'44/' -> '44' -> '/'
'45/' -> '45' -> '/'
'46/' -> '46' -> '/'
'47/' -> '47' -> ''
'48/' -> '48' -> '/'
'49/' -> '49' -> '/'

Why is in the case of 47, the slash at the end eaten up by the skipOver function ?
I tested all numbers from 0 to 1000, and it only occurs when the number is 47 (?!)

Can anyone confirm this, since it looks like such a weird bug to me ?

Kind regards,
Danny Arends

January 22, 2017
On Sunday, 22 January 2017 at 09:55:49 UTC, Danny Arends wrote:
> Hey all,
>
> Can anyone confirm this, since it looks like such a weird bug to me ?
>
> Kind regards,
> Danny Arends

The ASCII code for / is 47.
January 22, 2017
On Sunday, 22 January 2017 at 09:55:49 UTC, Danny Arends wrote:
> Hey all,
>
> I encountered some unexpected behavior in std.format, I was parsing Wavefront obj file, and ran into an issue. I updated the compiler to the latest stable version (// DMD64 D Compiler v2.072.2), however I think it's a Phobos related issue.
>
> [...]

Two further observations:

(Obs 1)

47 is ascii code for forwards slash '/'

(Obs 2)

Changing the line:

l.skipOver(x);

to:

l.skipOver(to!string(x));

Does not show the bug.
January 22, 2017
On Sunday, 22 January 2017 at 10:01:09 UTC, Danny Arends wrote:
> On Sunday, 22 January 2017 at 09:55:49 UTC, Danny Arends wrote:
>> Hey all,
>>
>> I encountered some unexpected behavior in std.format, I was parsing Wavefront obj file, and ran into an issue. I updated the compiler to the latest stable version (// DMD64 D Compiler v2.072.2), however I think it's a Phobos related issue.
>>
>> [...]
>
> Two further observations:
>
> (Obs 1)
>
> 47 is ascii code for forwards slash '/'
>
> (Obs 2)
>
> Changing the line:
>
> l.skipOver(x);
>
> to:
>
> l.skipOver(to!string(x));
>
> Does not show the bug.

This is not a bug.
But working as intended.
you call skip over with an (char[] skip, int overThis)
and skip over will do comparions like this (if (skip[pos] == overThis))
and since '\' == 47;
it will skip over that one.
January 22, 2017
On Sunday, 22 January 2017 at 10:30:14 UTC, Stefan Koch wrote:
> On Sunday, 22 January 2017 at 10:01:09 UTC, Danny Arends wrote:
>> On Sunday, 22 January 2017 at 09:55:49 UTC, Danny Arends wrote:
>>> Hey all,
>>>
>>> I encountered some unexpected behavior in std.format, I was parsing Wavefront obj file, and ran into an issue. I updated the compiler to the latest stable version (// DMD64 D Compiler v2.072.2), however I think it's a Phobos related issue.
>>>
>>> [...]
>>
>> Two further observations:
>>
>> (Obs 1)
>>
>> 47 is ascii code for forwards slash '/'
>>
>> (Obs 2)
>>
>> Changing the line:
>>
>> l.skipOver(x);
>>
>> to:
>>
>> l.skipOver(to!string(x));
>>
>> Does not show the bug.
>
> This is not a bug.
> But working as intended.
> you call skip over with an (char[] skip, int overThis)
> and skip over will do comparions like this (if (skip[pos] == overThis))
> and since '\' == 47;
> it will skip over that one.

Yeah I kind of figured that, however it is very confusing the skipOver() function, first tries to match an integer input as a ascii code.

However if this ascii code is NOT found (e.g. when x = 46, ascii code for '.') it promotes the integer to a string, and then skips passed the string 46.

I think the promotion of the input integer to string shouldn't happen, or should be clearly documented..

Greetings
Danny

January 22, 2017
On Sunday, 22 January 2017 at 11:20:18 UTC, Danny Arends wrote:
> On Sunday, 22 January 2017 at 10:30:14 UTC, Stefan Koch wrote:
>> On Sunday, 22 January 2017 at 10:01:09 UTC, Danny Arends wrote:
>>> On Sunday, 22 January 2017 at 09:55:49 UTC, Danny Arends wrote:
>>>> Hey all,
>>>>
>>>> I encountered some unexpected behavior in std.format, I was parsing Wavefront obj file, and ran into an issue. I updated the compiler to the latest stable version (// DMD64 D Compiler v2.072.2), however I think it's a Phobos related issue.
>>>>
>>>> [...]
>>>
>>> Two further observations:
>>>
>>> (Obs 1)
>>>
>>> 47 is ascii code for forwards slash '/'
>>>
>>> (Obs 2)
>>>
>>> Changing the line:
>>>
>>> l.skipOver(x);
>>>
>>> to:
>>>
>>> l.skipOver(to!string(x));
>>>
>>> Does not show the bug.
>>
>> This is not a bug.
>> But working as intended.
>> you call skip over with an (char[] skip, int overThis)
>> and skip over will do comparions like this (if (skip[pos] == overThis))
>> and since '\' == 47;
>> it will skip over that one.
>
> Yeah I kind of figured that, however it is very confusing the skipOver() function, first tries to match an integer input as a ascii code.
>
> However if this ascii code is NOT found (e.g. when x = 46, ascii code for '.') it promotes the integer to a string, and then skips passed the string 46.
>
> I think the promotion of the input integer to string shouldn't happen, or should be clearly documented..
>
> Greetings
> Danny

No it never promotes the integer to a string.
it compares a char to an uint.
You pass a string and an int to it.
And the elements of the string are getting compared to the uint
See this overload
https://dlang.org/phobos/std_algorithm_searching.html#.skipOver.2


January 22, 2017
Add a `writeln(l);` after the call to formattedRead().
January 24, 2017
On Sunday, 22 January 2017 at 11:20:18 UTC, Danny Arends wrote:
> On Sunday, 22 January 2017 at 10:30:14 UTC, Stefan Koch wrote:
>> On Sunday, 22 January 2017 at 10:01:09 UTC, Danny Arends wrote:
>>> On Sunday, 22 January 2017 at 09:55:49 UTC, Danny Arends wrote:
>>>> Hey all,
>>>>
>>>> I encountered some unexpected behavior in std.format, I was parsing Wavefront obj file, and ran into an issue. I updated the compiler to the latest stable version (// DMD64 D Compiler v2.072.2), however I think it's a Phobos related issue.
>>>>
>>>> [...]
>>>
>>> Two further observations:
>>>
>>> (Obs 1)
>>>
>>> 47 is ascii code for forwards slash '/'
>>>
>>> (Obs 2)
>>>
>>> Changing the line:
>>>
>>> l.skipOver(x);
>>>
>>> to:
>>>
>>> l.skipOver(to!string(x));
>>>
>>> Does not show the bug.
>>
>> This is not a bug.
>> But working as intended.
>> you call skip over with an (char[] skip, int overThis)
>> and skip over will do comparions like this (if (skip[pos] == overThis))
>> and since '\' == 47;
>> it will skip over that one.
>
> Yeah I kind of figured that, however it is very confusing the skipOver() function, first tries to match an integer input as a ascii code.
>
> However if this ascii code is NOT found (e.g. when x = 46, ascii code for '.') it promotes the integer to a string, and then skips passed the string 46.
>
> I think the promotion of the input integer to string shouldn't happen, or should be clearly documented..
>
> Greetings
> Danny

It really isn't if you understand how the types are operating when compiled. There is theoretically no such thing as a character when it comes to actual data types. It's nothing but a number on the OS level. Unless it's a Unicode etc. then it's a sequence of numbers to form code points