June 26th, 2024

Is there a built-in way in C++/WinRT to get the string name for a Windows Runtime enum?

Say you have a value from a Windows Runtime enumeration and you want to convert it to a corresponding string. You can do this in C# with the ToString() method.

void LogStatus(AsyncStatus status)
{
    Log("Status: " + status.ToString());
}

But C++/WinRT doesn’t provide a ToString() method.

C++/WinRT produces standard C++, and at least as of C++20, there is no standard for reflection, so there is no standard C++ way for converting a value to a string.¹

 

C++/WinRT could have included value-to-string conversion in its code generation, but it doesn’t. Partly because it’s hoping that the C++ language will provide reflection. And partly because experience has told us that value-to-string conversion is rarely useful in production.

For one thing, you would never want to do a value-to-string conversion for a string to display to the user. Those strings are going to be in English (which may not be appropriate for your audience), and they will require domain-specific knowledge to interpret (which is definitely not appropriate for your audience).²

In practice, stringification is useful only for logging purposes, and people who have done this say that generally regret it and wish they had just logged as plain integers.

One reason is that if new values are added to the enum after the program is compiled, the program won’t know how to convert those new values to strings, so it’ll presumably log them as integers. And then a newer version of the program is compiled which understands these new values, and those new values are now logged as strings. The same value is now being logged in two different ways, and the back end processing has to merge those two columns into one. Better to just leave them as integers and let the back end do the stringification, so that it’s consistent. If a new enum value is added, you just add it to the back end and the strings are all updated, even for values coming from older versions of the program that predated the new value.

Another reason is that it is much easier to parse integers on the back end. If you logged them as strings, then the back end would have to have a reverse parser to convert them back to values if it wanted to do further processing.

You can do the value-to-string conversion on your back end, probably as a final step before displaying them on a dashboard.

¹ That hasn’t stopped people from coming up with clever hacks that work under certain conditions. The most ambitious of those clever hacks is probably magic_enum.

A proposal for reflection has made significant progress for C++26 and may even have been approved by the time you read this.

² The exception to this would be a diagnostic tool whose audience is other software developers, not the general user population. If you are really motivated, you could write a tool that uses the xlang library (the same library that C++/WinRT itself uses) to parse the winmd files and produce stringification functions.

Alternatively, you could write a C# program that ingests the winmd files and uses C# reflection to produce the stringifiers. That’s what my colleague Alexander Sklar did: CppWinRT.Builders.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Paulo Pinto

    > Partly because it’s hoping that the C++ language will provide reflection.

    Yeah, since 2016, that was the lame excuse for not providing C++/CX level of quality tooling in Visual Studio for C++/WinRT, which keeps the whole experience of using C++/WinRT in Visual Studio back to Visual C++ 6.0 with ATL, but it seems that is what Windows developer team really likes, and cannot understand why we would enjoy anything else.

    But hey, at least now it...

    Read more
  • Antonio Rodríguez

    Be it in logs, or in an error alert/dialog, I agree, integer codes are required. But also presenting a string description can hasten the diagnose. Just be sure to always show the error code, and then, if available, the description. That way, logs can be easily parsed but retain their readability, and dialogs are useful for the technical audience (the description gives a quick glance at the problem, and the code can be looked up...

    Read more