views:

51

answers:

4

Is there a quick way of outputting the names of enumerated values? I suppose you know what I mean, and at all this isn't possible as of course all of this data becomes irrelevant during compile process, but I'm using MSVC in debugging mode, so is it possible?

A: 

Unfortunately not. All of the enum names are lost by the compiler. The PDB file has them, so the debugger can work it out, but otherwise the only way to do it would be to write a function that does a switch and returns a string.

Stewart
"The PDB file has them": How to access them?
oh boy
I don't know the name of it, but there is a library that you can link with to get information out of the PDB.
dash-tom-bang
It's the "Debug Interface Access SDK" (http://msdn.microsoft.com/en-us/library/x93ctkx8.aspx)
Michael Burr
You really don't want to be accessing this at runtime though - PDB files are huge and reading them just to figure out the string name of an enum value will be very slow. The meta macro example above is much more efficient
Stewart
but if you load all of the info out of the PDB that you need at once it may not be too bad (amortized over the life of the program, anyway).
dash-tom-bang
True, but if you know what info you need ahead of time so you can selectively load it, it would be much faster to encode that info in the program.
Stewart
+1  A: 

I just put the enum names in a lookup table (or you could use a map<>) with the enum value as a key and have a function perform the lookup.

It's low-tech, but usually not too much of a pain.

In some projects I'd have a weird header/macro arrangement that could build the enum definition using a single declaration-like item per enum name. My opinon on how that technique works wavers back and forth between "handy" or "kludgy" though.

Michael Burr
That is what I was trying to avoid :)
oh boy
+1  A: 

Metamacros cause all sorts of havoc on Intellisense and the like, but they can make this task easy...

#define MY_ENUMS(e_) \
   e_(Enum_A), \
   e_(Enum_B), \
   e_(Enum_C), \

#define ENUM_EXPANDER(e_)  e
enum MyEnums
{
   MY_ENUMS(ENUM_EXPANDER)
   CountOfMyEnums
};

#define STRING_EXPANDER(e_)  #e_
const char* g_myEnumStrings[] =
{
   MY_ENUMS(STRING_EXPANDER)
};

Possibly even

#define CASE_EXPANDER(e_)  case e_: return #e_;
const char* GetEnumName(MyEnums e)
{
   switch (e)
   {
      MY_ENUMS(CASE_EXPANDER)

   default:
      return "Invalid enum value";
   }
}

Different "expander macros" can be used to fill maps or other data structures of your choice. I've used this sort of horror to parse enums out of config files (so the person authoring the config file could use the enum rather than the index).

dash-tom-bang
This may not be what you want, but is a different approach to the problem. Reading the PDB is fine if you generate it, but if you're distributing the code and intending to use the enum values automatically in the UI somehow, you'll need a different solution.
dash-tom-bang
+1  A: 

This is common C++ problem, that is solved using "Typesafe enum pattern". Usually this is done using some crazy precompiler definitions, or code generators. Quick search for "Typesafe enum pattern C++" can give you these ways. Personally, I have my own code generator for C++ enumerations, which is executed as MSVC custom build step for h-files with enumerations.

Alex Farber
Note: You have 1,337 rep.
oh boy
@oh boy: Noted! I won't upvote then.. :-P
Marcus Lindblom
@oh boy, Marcus Lindblom - what do you mean?
Alex Farber
1337 = leet = "elite". I thought I was special the other day when I had 1024 rep, but 1337 is something to aspire to. :)
dash-tom-bang