Thread overview
Compile time int to string conversion in BetterC
Aug 17, 2022
Ogi
Aug 17, 2022
Dennis
Aug 18, 2022
Paul Backus
Aug 19, 2022
bauss
Aug 19, 2022
Paul Backus
Aug 19, 2022
bauss
Aug 19, 2022
Ogi
August 17, 2022

It’s 2022 already and BetterC still imposes limits at compile time and makes things awkward.

I have 3 integer enums that represents my library version. And I want to generate a "1.2.3" enum from them. This is a trivial thing to do in standard D but I can’t find a way to do it with BetterC enabled. I can’t use to, text, sformat or toChars, as none of them is compatible with BetterC. And I can’t use sprintf either because ‘stdc’ is not available at compile time.

On the other hand, string to integer conversion is simple: just ‘mixin’ it! So as a workaround, I put numbers into private string enums, and the integer enums are generated from them. But this is not nice.

Maybe I’m missing something?

August 17, 2022

On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:

>

Maybe I’m missing something?

I had the same problem, and came up with the following trick:

enum itoa(int i) = i.stringof;

enum major = 3;
enum minor = 2;
enum patch = 1;

enum versionString = itoa!major ~ "." ~ itoa!minor ~ "." ~ itoa!patch;

static assert(versionString == "3.2.1");

Now I need to warn you that the output of stringof is technically implementation defined per the specification, so you shouldn't rely on it. In practice this doesn't stop people, and I don't think integers will ever not be printed as a string of base 10 digits.

August 17, 2022

On 8/17/22 6:38 AM, Dennis wrote:

>

On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:

>

Maybe I’m missing something?

I had the same problem, and came up with the following trick:

enum itoa(int i) = i.stringof;

I have the same thing in my code:

enum intStr(int x) = x.stringof;

The reason you do this is to shoehorn things that aren't technically ints (such as enum types) into ints. This avoids weirdness like cast(foo)bar or whatnot that might happen if you just use stringof on any expression.

>

Now I need to warn you that the output of stringof is technically implementation defined per the specification, so you shouldn't rely on it. In practice this doesn't stop people, and I don't think integers will ever not be printed as a string of base 10 digits.

Yeah, I wouldn't worry about stringof for ints.

-Steve

August 18, 2022

On Wednesday, 17 August 2022 at 11:38:31 UTC, Steven Schveighoffer wrote:

>

On 8/17/22 6:38 AM, Dennis wrote:

>

On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:

>

Maybe I’m missing something?

I had the same problem, and came up with the following trick:

enum itoa(int i) = i.stringof;

I have the same thing in my code:

enum intStr(int x) = x.stringof;

I merged a version of this into Phobos (for internal use):

https://github.com/dlang/phobos/blob/v2.100.1/std/conv.d#L5986-L5987

It also comes with a unit test, so we don't get surprise breakage if the behavior of .stringof ever changes.

August 19, 2022

On Wednesday, 17 August 2022 at 10:38:33 UTC, Dennis wrote:

>

I had the same problem, and came up with the following trick:

enum itoa(int i) = i.stringof;

enum major = 3;
enum minor = 2;
enum patch = 1;

enum versionString = itoa!major ~ "." ~ itoa!minor ~ "." ~ itoa!patch;

static assert(versionString == "3.2.1");

Nice! Thank you, I’ll use this.

August 19, 2022

On Thursday, 18 August 2022 at 22:00:06 UTC, Paul Backus wrote:

>

On Wednesday, 17 August 2022 at 11:38:31 UTC, Steven Schveighoffer wrote:

>

On 8/17/22 6:38 AM, Dennis wrote:

>

On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:

>

Maybe I’m missing something?

I had the same problem, and came up with the following trick:

enum itoa(int i) = i.stringof;

I have the same thing in my code:

enum intStr(int x) = x.stringof;

I merged a version of this into Phobos (for internal use):

https://github.com/dlang/phobos/blob/v2.100.1/std/conv.d#L5986-L5987

It also comes with a unit test, so we don't get surprise breakage if the behavior of .stringof ever changes.

Is there a reason why .stringof is implementation defined and not clearly defined in the spec how types and declarations should be treated when being "converted to a string"?

I find it really odd that it's implementation defined and you essentially can't rely on it anywhere.

It's something that has baffled me a lot.

Like are there something I'm missing that means it cannot be specified?

August 19, 2022

On Friday, 19 August 2022 at 10:22:25 UTC, bauss wrote:

>

Is there a reason why .stringof is implementation defined and not clearly defined in the spec how types and declarations should be treated when being "converted to a string"?

I find it really odd that it's implementation defined and you essentially can't rely on it anywhere.

It's something that has baffled me a lot.

Like are there something I'm missing that means it cannot be specified?

Basically, .stringof is what the compiler uses when it needs to display something in an error message. If it were locked down in the spec, then making improvements to error messages would in some cases require a deprecation cycle.

That said, it might still be worth specifying the behavior in a few specific cases—e.g., guaranteeing that .stringof on an integer value will always produce a valid integer literal.

August 19, 2022

On Friday, 19 August 2022 at 13:47:41 UTC, Paul Backus wrote:

>

On Friday, 19 August 2022 at 10:22:25 UTC, bauss wrote:

>

Is there a reason why .stringof is implementation defined and not clearly defined in the spec how types and declarations should be treated when being "converted to a string"?

I find it really odd that it's implementation defined and you essentially can't rely on it anywhere.

It's something that has baffled me a lot.

Like are there something I'm missing that means it cannot be specified?

Basically, .stringof is what the compiler uses when it needs to display something in an error message. If it were locked down in the spec, then making improvements to error messages would in some cases require a deprecation cycle.

That said, it might still be worth specifying the behavior in a few specific cases—e.g., guaranteeing that .stringof on an integer value will always produce a valid integer literal.

Yeah I mean not all of its behavior has to be implementation defined.