www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Possible bug in skipOver() from std/algorithm/searching.d

reply Danny Arends <Danny.Arends gmail.com> writes:
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
Jan 22
next sibling parent Daniel N <ufo orbiting.us> writes:
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.
Jan 22
prev sibling next sibling parent reply Danny Arends <Danny.Arends gmail.com> writes:
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.
Jan 22
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
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.
Jan 22
parent reply Danny Arends <Danny.Arends gmail.com> writes:
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
Jan 22
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
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
Jan 22
prev sibling parent Bauss <jj_1337 live.dk> writes:
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
Jan 24
prev sibling parent Chris Wright <dhasenan gmail.com> writes:
Add a `writeln(l);` after the call to formattedRead().
Jan 22