Comment #0 by kodlists-dlang — 2013-03-23T10:14:23Z
$ cat conv_bug.d
import std.conv;
void main()
{
auto var = to!int("0x123");
}
$ rdmd conv_bug.d
std.conv.ConvException@/usr/include/dmd/phobos/std/conv.d(1612): Unexpected 'x' when converting from type string to type int
Comment #1 by andrej.mitrovich — 2013-03-23T10:39:40Z
Comment #2 by kodlists-dlang — 2013-04-15T19:25:49Z
(In reply to comment #1)
> This might end up being rejected like Issue 7692. See comment
> https://github.com/D-Programming-Language/phobos/pull/835#discussion_r1764414.
The reason given to close issue 7692 is wrong. In D a hexadecimal number is prefixed with 0x. Not being able to recognize a valid D hexadecimal number is a bug in to!int().
Below is what C's strtol() does and parse!int() should behave same.
value = strtol("0xyz", &leftover, 0); // value == 0, leftover == "xyz"
value = strtol("0xyz", &leftover, 16); // value == 0, leftover == "xyz"
value = strtol("0x0x", &leftover, 0); // value == 0, leftover == "x"
value = strtol("0x0x", &leftover, 16); // value == 0, leftover == "x"
value = strtol("0x0x", &leftover, 10); // value == 0, leftover == "x0x"
value = strtol("abcd", &leftover, 0); // value == 0, leftover == "abcd"
value = strtol("abcd", &leftover, 16); // value == 0xabcd, leftover == ""
Comment #3 by cauterite — 2015-11-06T12:44:03Z
I can see only one reasonable(ish) solution here:
Patch toImpl() to detect prefixes like "0x" and "0b", so it calls parse() with the appropriate radix. This may not be as much of a problem as patching parse() itself, since toImpl() either parses the whole input successfully or throws.
However, if the caller is not fully aware that to() accepts these alternative number syntaxes, it could easily cause subtle bugs. Additionally, having parse() and to() operate differently doesn't sit right with me.
The only other option I can think of would be to provide a separate function specifically for parsing D-style numeric literals, but this is out of the scope of std.conv
Unless anyone has a better idea, I suggest WONTFIX. It's not an *especially* common problem, and parse() with explicit radix makes it trivial for callers to deal with it themselves.
Comment #4 by b2.temp — 2015-11-07T02:00:55Z
Agree, furthemore there are others prefix/suffix notations:
- 12345678h: several hex editors , IDA
- #12345678: colors, html, css
- $12345678: Pascal
- 0X or 0x
- and maybe others...
so even if 0x is handled ,there are several cases where the user has to parse the prefix/suffix by hand anyway.
Comment #5 by b2.temp — 2016-04-02T01:24:11Z
> In D a hexadecimal number is prefixed with 0x. Not being able to recognize a valid D hexadecimal number is a bug in to!int().
And then even if done, someone will come and report that `to()` is not able to convert "0x1_2_3_4_P5" (valid D hexadecimal litteral)!
So your argument is invalid.
Comment #6 by issues.dlang — 2016-04-02T15:57:26Z
I would point out that while to!int("0x123"); isn't going to work, to!int("123", 16); will. e.g.
import std.conv;
void main()
{
auto str = to!string(42, 16);
assert(str == "2A", str);
auto i = to!int(str, 16);
assert(i == 42);
}
So, if you check for 0x and strip it off before feeding the string to to!int, then it will do the conversion. It just won't work with the prefix on it. And while having to!int check for the prefix as well as anything else that's valid in a numeric literal in D might be nice in some cases, it would slow down to!int for everything else, which really isn't a good tradeoff given how much to!int is used. A conversion function specifically for literals might make sense, but I have to concur that doing it with std.conv.to isn't worth it.