www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Value of type enum members

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
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
}
Jan 19
next sibling parent Paul Backus <snarwin gmail.com> writes:
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?
[...]
 void main()
 {
     pragma(msg, TENUM.foo);    // T(2)
     pragma(msg, TENUM.bar);    // T(3)
     writeln(TENUM.foo);        // foo
     writeln(TENUM.bar);        // bar
 }
There is no difference in the values, they're just being printed differently. pragma(msg) uses the compiler's internal string-conversion routines, and writeln uses the ones from Phobos, so it's not too surprising that they would display some values differently.
Jan 19
prev sibling parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
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.
Jan 19