www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 01777777777777777777777 [std.conv.octal]

reply kdevel <kdevel vogtner.de> writes:
```
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
next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
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
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/6/22 13:32, Adam D Ruppe wrote:

And with U or L as needed:

   auto w = octal!"1777777777777777777777UL";

Ali
Apr 06
prev sibling parent reply MoonlightSentinel <moonlightsentinel disroot.org> writes:
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
parent reply kdevel <kdevel vogtner.de> writes:
On Thursday, 7 April 2022 at 12:52:20 UTC, MoonlightSentinel 
wrote:
 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)
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>
Apr 07
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
parent reply kdevel <kdevel vogtner.de> writes:
On Thursday, 7 April 2022 at 15:01:02 UTC, Steven Schveighoffer 
wrote:
 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 was never disputed.
 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
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
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
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/7/22 12:38 PM, Adam Ruppe wrote:
 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.
Yes. In fact, this compiles and is just... not useful. ```d assert(octal!0b1111001 == octal!0x79); ``` -Steve
Apr 07
prev sibling parent reply kdevel <kdevel vogtner.de> writes:
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:
 That was not my objection. My point is that it won't compile 
 for certain valid octal literals.
They're not actually octal literals.
You certainly don't want to dispute that 01777777777777777777777 is actually an octal literal whose value fits in a ulong?
 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 method
Made 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
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/7/22 3:18 PM, kdevel wrote:
 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:
 That was not my objection. My point is that it won't compile for 
 certain valid octal literals.
They're not actually octal literals.
You certainly don't want to dispute that     01777777777777777777777 is actually an octal literal whose value fits in a ulong?
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.
 
 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
next sibling parent reply user1234 <user1234 12.de> writes:
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
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/7/22 4:18 PM, user1234 wrote:
 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; ```
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. -Steve
Apr 07
prev sibling parent reply kdevel <kdevel vogtner.de> writes:
On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer 
wrote:
[...]
 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.
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.
 [...]
 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
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/7/22 4:52 PM, kdevel wrote:
 On Thursday, 7 April 2022 at 19:59:24 UTC, Steven Schveighoffer wrote:
 [...]
 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.
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.
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.
 [...]
 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.
No imagination required -- compiler error.
 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
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
parent kdevel <kdevel vogtner.de> writes:
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
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
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