Usually, enum
values are simple compiler-incremented values or are set directly to an integral literal, and so the values can be deduced easily or seen directly by looking at the source file.
However, sometimes enum
values are used to set an in-class constant equal to a value defined elsewhere or to the result of a compile-time expression that isn't easily duplicated.
Is there a way to get Windbg to show me the actual value of each enum
member for those trickier cases?
Consider this small struct:
struct foo
{
enum enum1
{
enum1_val1_ = 5,
enum1_val2_,
};
enum enum2
{
enum2_val1_ = 0x0001,
enum2_val2_ = 0x0010,
};
enum
{
// assume these come from complicated compile-time expressions
some_class_constant_ = 86,
another_one_ = 99,
};
};
The fastest way is to use the dt
command, using switches -r
(recurse, which you need to list the enum
members) and -v
(verbose, which you need to list enum
s at all):
0:000> dt -r -v foo
LangTestingD!foo
struct foo, 3 elements, 0x1 bytes
Enum enum1, 2 total enums
enum1_val1_ = 0n5
enum1_val2_ = 0n6
Enum enum2, 2 total enums
enum2_val1_ = 0n1
enum2_val2_ = 0n16
Enum <unnamed-tag>, 2 total enums
some_class_constant_ = 0n86
another_one_ = 0n99
You can see that it lists the values of each enum, even the unnamed one. Multiple unnamed enums will all be listed correctly.
The problem with dt -r -v foo
is that it lists every single member of foo
: all data members, all function members, all enums, and it tries to recurse into each one and lists its members. If foo
is a complex class, which is rather easy to get with inheritance, the output will be huge, and it'll be difficult to find that one enum you're looking for.
So the next option is to tell dt
which enum you want, specifically:
0:000> dt foo::enum1
LangTestingD!foo::enum1
enum1_val1_ = 0n5
enum1_val2_ = 0n6
Okay, great! But how about that unnamed enum? Well, you say, check out the output above, where it uses <unnamed-tag>
. Maybe we can use that.
0:000> dt foo::<unnamed-tag>
Couldn't resolve error at 'foo::<unnamed-tag>'
It actually will work, but you need to use a couple extra switches. When you combine -n
(following parameter is a name) and -y
(match the next parameter as a name prefix) then it, sort of, works:
0:000> dt -n -y foo::<unnamed-tag>
LangTestingD!foo::<unnamed-tag>
some_class_constant_ = 0n86
However, only the first value is listed. Even worse, if there are multiple unnamed enums, only the first value of the first one is listed. Often this will be enough, as multiple unnamed enums isn't too common, but if you absolutely need them, you'll have to use -r -v
and just find them in the output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With