On Tuesday, 19 January 2021 at 20:27:30 UTC, Andrey Zherikov wrote:
Could someone please explain why there is a difference in values between compile-time and run-time?

struct T
{
    int i;
    this(int a) {i=a;}
}

enum TENUM : T
{
    foo = T(2),
    bar = T(3),
}

void main()
{
    pragma(msg, TENUM.foo);    // T(2)
    pragma(msg, TENUM.bar);    // T(3)
    writeln(TENUM.foo);        // foo
    writeln(TENUM.bar);        // bar
}

TL;DR `pragma(msg, x)` prints the value of `x` usually casted to the enumeration (base) type, while `std.conv.to!string(x)` prints the name of the enum member corresponding to the value of `x`.

Both `pragma(msg, ...)` and `std.conv.to!string(..)` (what is used under the hood by `writeln(..)`) take somewhat arbitrary decisions about formating enum members, neither of which is the "right" one, as there's no rule saying which is better.

In general, `std.conv.to!string(..)` tries to use format that is meant to be friendly to the end-users of your program, while `pragma(msg, ...)` is a CT debugging tool and it tries to stay close to the compiler's understanding of your program.

For example:

void main()
{
    import std.stdio;

    enum E1 { a = 1, b, c }
    enum E2 { x = "4" }
    enum E3 : string { y = "5" }

    // 1.0 2L cast(E1)3 4 5
pragma(msg, 1.0, " ", long(2), " ", E1.c, " ", E2.x, " ", E3.y);

    // 1 2 c x y
    writeln(1.0, " ", long(2), " ", E1.c, " ", E2.x, " ", E3.y);
}


End-users generally don't care about the specific representations of numbers in your program, while on the other hand that's a crucial detail for the compiler and you can see this bias in the output.


Reply via email to