| |
| Posted by Petar Kirov [ZombineDev] in reply to Andrey Zherikov | PermalinkReply |
|
Petar Kirov [ZombineDev]
Posted in reply to Andrey Zherikov
| 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.
|