digitalmars.D - 01777777777777777777777 [std.conv.octal]
- kdevel (25/25) Apr 06 2022 ```
- Adam D Ruppe (5/9) Apr 06 2022 The error message isn't smart enough to suggest this, but putting
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/4) Apr 06 2022 On 4/6/22 13:32, Adam D Ruppe wrote:
- MoonlightSentinel (3/4) Apr 07 2022 Yes. I've changed to hint s.t. it suggests the string version.
- kdevel (32/36) Apr 07 2022 Commendable, but my question related to the implementation
- Steven Schveighoffer (11/15) Apr 07 2022 `octal!123` is a template, and as such, must be valid D code. Your
- kdevel (19/27) Apr 07 2022 That was never disputed.
- Adam Ruppe (7/9) Apr 07 2022 They're not actually octal literals.
- Steven Schveighoffer (6/17) Apr 07 2022 Yes. In fact, this compiles and is just... not useful.
- kdevel (10/21) Apr 07 2022 You certainly don't want to dispute that
- Steven Schveighoffer (19/34) Apr 07 2022 but that's not what you gave to the compiler. for
- user1234 (7/17) Apr 07 2022 I dont see any real problem with x1 type because you can request
- Steven Schveighoffer (7/30) Apr 07 2022 Yes, but auto is convenient, template IFTI will not carry forward that
- kdevel (10/18) Apr 07 2022 On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer
- Steven Schveighoffer (7/28) Apr 07 2022 Please tell me the percentage of octal literals written in code
- Steven Schveighoffer (9/11) Apr 07 2022 Octal literals are actually processed just fine in the D parser. You
- kdevel (3/6) Apr 07 2022 Just works.
- Walter Bright (2/4) Apr 08 2022 ImportC follows the C11 Standard, which include octal literals.
``` auto w = 01777777777777777777777; ``` ``` Error: octal literals `01777777777777777777777` are no longer supported, use `std.conv.octal!1777777777777777777777` instead ``` It's worth a try: ``` auto w = std.conv.octal!1777777777777777777777; ``` ``` Error: integer overflow ``` Quote from `std/conv.d`: ``` template octal(alias decimalInteger) if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger))) { enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger)); } ``` Does it *feel* wrong to you, too?
Apr 06 2022
On Wednesday, 6 April 2022 at 20:27:10 UTC, kdevel wrote:It's worth a try: ``` auto w = std.conv.octal!1777777777777777777777; ```The error message isn't smart enough to suggest this, but putting quotes around it ought to work. auto w = std.conv.octal!"1777777777777777777777"; like that.
Apr 06 2022
On 4/6/22 13:32, Adam D Ruppe wrote: And with U or L as needed: auto w = octal!"1777777777777777777777UL"; Ali
Apr 06 2022
On Wednesday, 6 April 2022 at 20:27:10 UTC, kdevel wrote:Does it *feel* wrong to you, too?Yes. I've changed to hint s.t. it suggests the string version. [PR](https://github.com/dlang/dmd/pull/13958)
Apr 07 2022
On Thursday, 7 April 2022 at 12:52:20 UTC, MoonlightSentinel wrote:On Wednesday, 6 April 2022 at 20:27:10 UTC, kdevel wrote:Commendable, but my question related to the implementation ``` template octal(alias decimalInteger) if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger))) { enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger)); } ``` For this code I can hardly imagine an enhancement in order to cover decimalInteger > ulong.max. There is also a naming issue: Do we name parameters after their representation (decimal) or after their function (octal)? A better name is probably ``octalLiteralDisguisedAsDecimalLiteral``. The documentation [1], [2] does not explicitly mention the inherent limitation of the quoteless conversion. The two forms ``octal!<literal>`` and ``octal!<literal>"`` are treated as interchangeable. In [3] we read 4. C-style octal integer notation was deemed too easy to mix up with decimal notation; it is only fully supported in string literals. D still supports octal integer literals interpreted at compile time through the std.conv.octal template, as in octal!167. There is no mention of any restriction of the argument domain at all. **TL;DR**: Deprecate and remove template octal(alias decimalInteger). [1] <https://dlang.org/library/std/conv/octal.html> [2] <https://dlang.org/phobos/std_conv.html#octal> [3] <https://dlang.org/spec/lex.html#integerliteral>Does it *feel* wrong to you, too?Yes. I've changed to hint s.t. it suggests the string version. [PR](https://github.com/dlang/dmd/pull/13958)
Apr 07 2022
On 4/7/22 10:00 AM, kdevel wrote:The documentation does not explicitly mention the inherent limitation of the quoteless conversion. The two forms ``octal!<literal>`` and ``octal!<literal>"`` are treated as interchangeable.`octal!123` is a template, and as such, must be valid D code. Your integer is not valid D code, so it doesn't compile. That doesn't mean it won't compile for valid integers. The string version is guaranteed to work, as long as the resulting number fits, which is why it should be suggested by the compiler. But removing the support for regular integers isn't necessary. A spec documentation update would be good too. And OMG, that implementation for the non-string version is terrible, we should not be doing that for CTFE. -Steve
Apr 07 2022
On Thursday, 7 April 2022 at 15:01:02 UTC, Steven Schveighoffer wrote:On 4/7/22 10:00 AM, kdevel wrote:That was never disputed.The documentation does not explicitly mention the inherent limitation of the quoteless conversion. The two forms ``octal!<literal>`` and ``octal!<literal>"`` are treated as interchangeable.`octal!123` is a template, and as such, must be valid D code. Your integer is not valid D code, so it doesn't compile.That doesn't mean it won't compile for valid integers.That was not my objection. My point is that it won't compile for certain valid octal literals. Consider this implementation ``` template octal(ubyte decimalInteger) { enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger)); } ``` Your argument applies to this code accordingly. But you would certainly halt it in the code review. Does it really make a qualitative difference if one writes ubyte or – as implicitly in the current code – ulong? Stefan BTW: I haven't yet taken a peek into the C header inclusion stuff. How are octal literals processed in that code?
Apr 07 2022
On Thursday, 7 April 2022 at 16:28:39 UTC, kdevel wrote:That was not my objection. My point is that it won't compile for certain valid octal literals.They're not actually octal literals. The implementation is (ridiculously) overcomplicated - ironically, as a result of code review nitpicking types - but the concept isn't: it *pretends* it is an octal literal. This is a convenience method that is not expected to work for all possible values, which is why the string one exists.
Apr 07 2022
On 4/7/22 12:38 PM, Adam Ruppe wrote:On Thursday, 7 April 2022 at 16:28:39 UTC, kdevel wrote:Yes. In fact, this compiles and is just... not useful. ```d assert(octal!0b1111001 == octal!0x79); ``` -SteveThat was not my objection. My point is that it won't compile for certain valid octal literals.They're not actually octal literals. The implementation is (ridiculously) overcomplicated - ironically, as a result of code review nitpicking types - but the concept isn't: it *pretends* it is an octal literal. This is a convenience method that is not expected to work for all possible values, which is why the string one exists.
Apr 07 2022
On Thursday, 7 April 2022 at 16:38:58 UTC, Adam Ruppe wrote:On Thursday, 7 April 2022 at 16:28:39 UTC, kdevel wrote:You certainly don't want to dispute that 01777777777777777777777 is actually an octal literal whose value fits in a ulong?That was not my objection. My point is that it won't compile for certain valid octal literals.They're not actually octal literals.The implementation is (ridiculously) overcomplicated - ironically, as a result of code review nitpicking types - but the concept isn't: it *pretends* it is an octal literal.This concept is dubious and that is what bothers me.This is a convenience methodMade to save two keystrokes after having typed six additional ones compared to C/C++?that is not expected to work for all possible values, which is why the string one exists.The method does not work for most of the possible octal literals whose values fit in a ulong. I would call it an inconvenience method.
Apr 07 2022
On 4/7/22 3:18 PM, kdevel wrote:On Thursday, 7 April 2022 at 16:38:58 UTC, Adam Ruppe wrote:but that's not what you gave to the compiler. for `octal!1777777777777777777777`, the number part of that expression isn't a valid literal that fits in a ulong.On Thursday, 7 April 2022 at 16:28:39 UTC, kdevel wrote:You certainly don't want to dispute that 01777777777777777777777 is actually an octal literal whose value fits in a ulong?That was not my objection. My point is that it won't compile for certain valid octal literals.They're not actually octal literals.The method does not work for most of the possible octal literals whose values fit in a ulong. I would call it an inconvenience method.It works for all numbers below 288,230,376,151,711,744 (i.e. up to 58 bits). So, yeah, not all of them. But many of them. But I kind of agree with you that the integer one is full of problems. Another problem I just realized: ```d auto x1 = octal!17777777777; auto x2 = octal!"17777777777"; pragma(msg, typeof(x1)); // long pragma(msg, typeof(x2)); // int ``` Why? because `octal(T)` takes the type of `T` And there's no way to fix it. Because you'd want `octal!1L` to be long, so you can't just look at the value. We might want to just undocument the integer version. -Steve
Apr 07 2022
On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer wrote:Another problem I just realized: ```d auto x1 = octal!17777777777; auto x2 = octal!"17777777777"; pragma(msg, typeof(x1)); // long pragma(msg, typeof(x2)); // int ``` Why? because `octal(T)` takes the type of `T` And there's no way to fix it. Because you'd want `octal!1L` to be long, so you can't just look at the value.I dont see any real problem with x1 type because you can request to have it as `int` without cast ``` int x1 = octal!17777777777; ```
Apr 07 2022
On 4/7/22 4:18 PM, user1234 wrote:On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer wrote:Yes, but auto is convenient, template IFTI will not carry forward that ability to assign to an int, etc. I'd say we just undocument (and don't deprecate) the numeric form. Anyone who uses it can continue to do so, and once the compiler stops suggesting using it, I can't see a good reason to do it. -SteveAnother problem I just realized: ```d auto x1 = octal!17777777777; auto x2 = octal!"17777777777"; pragma(msg, typeof(x1)); // long pragma(msg, typeof(x2)); // int ``` Why? because `octal(T)` takes the type of `T` And there's no way to fix it. Because you'd want `octal!1L` to be long, so you can't just look at the value.I dont see any real problem with x1 type because you can request to have it as `int` without cast ``` int x1 = octal!17777777777; ```
Apr 07 2022
On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer wrote: [...]For the record: 1 - 2^54 / 2^64 = .9843. I.e. for 98.4 % of all possible values fitting in a ulong ```template octal (alias decimalInteger)``` does **not** work.The method does not work for most of the possible octal literals whose values fit in a ulong. I would call it an inconvenience method.It works for all numbers below 288,230,376,151,711,744 (i.e. up to 58 bits). So, yeah, not all of them. But many of them.[...] We might want to just undocument the integer version.I strongly recommend deprecation and removal. Imagine what happens if someone forgets to type the quotation marks and gets a type which is wider than expected. The abolishment of the leading-zero octals shall not introduce another error category.
Apr 07 2022
On 4/7/22 4:52 PM, kdevel wrote:On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer wrote: [...]Please tell me the percentage of octal literals written in code (including all C code) that are in that range. Remember, these are *literals*, not values that are in memory.For the record: 1 - 2^54 / 2^64 = .9843. I.e. for 98.4 % of all possible values fitting in a ulong ```template octal (alias decimalInteger)``` does **not** work.The method does not work for most of the possible octal literals whose values fit in a ulong. I would call it an inconvenience method.It works for all numbers below 288,230,376,151,711,744 (i.e. up to 58 bits). So, yeah, not all of them. But many of them.No imagination required -- compiler error.[...] We might want to just undocument the integer version.I strongly recommend deprecation and removal. Imagine what happens if someone forgets to type the quotation marks and gets a type which is wider than expected.The abolishment of the leading-zero octals shall not introduce another error category.Who cares? It's a compiler error if it doesn't work. -Steve
Apr 07 2022
Note, Adam already answered the other questions. On 4/7/22 12:28 PM, kdevel wrote:BTW: I haven't yet taken a peek into the C header inclusion stuff. How are octal literals processed in that code?Octal literals are actually processed just fine in the D parser. You even get a valid number out of it. In fact, technically the grammar is all still there intact. But then the compiler just uses that parsed value to display the error message. I would expect ImportC to use the same code, and just not display the error. -Steve
Apr 07 2022
On Thursday, 7 April 2022 at 17:28:32 UTC, Steven Schveighoffer wrote:[...] I would expect ImportC to use the same code, and just not display the error.Just works.
Apr 07 2022
On 4/7/2022 9:28 AM, kdevel wrote:BTW: I haven't yet taken a peek into the C header inclusion stuff. How are octal literals processed in that code?ImportC follows the C11 Standard, which include octal literals.
Apr 08 2022