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.