Friday 15 January 2016

Enum's forward declarations


C++ Katie (@katie_cpp :) wrote a blogpost* about the new C++11 enums. First I was reluctant to read it, but then I risked a quick look, and indeed, I learned something new.

As in the last couple of years I have been using Visual Studio most of the time, it came natural to me that I can forward declare enums:
  enum MsgType;  // we are in Visual Studio!

  class C
  {
  public:
    bool process(MsgType msg);
  };
but it seems to be only a nonstandard language extension, as normally it's shouldn't be possible:
"It’s because the underlying type of enum is not known. The compiler needs to know how many bytes will be required to store the enum and it cannot be decided based on the forward declaration like above. It’s necessary to see the biggest value stored inside this enum."
Yessss, I can dimly recollect that in the past I couldn't do that (gcc), but then I tried once again, and Visual Studio let me get away with it. Thus VS-compiler seems to default enum's size in such a case to int. With C++11's scoped enums, this behaviour is standardized:
"Let’s try the same with enum class. Now it works! ... The underlying type of enum class is implicitly known by the compiler (it’s int by default)."
As a collorary to the compiler's conundrum with plain enums, there's a catch I wasn't aware of (or didn't think of it at first, after some hours of debugging I'd get it probably):
"Another consequence of unknown underlying type appears when the C++98 enum should be a struct member. The struct size can be different when the code is compiled on various machines!"
That can be a source of some nasty, hard to find bugs, believe me!

And there's a second thing I didn't know, namely that it's possible to specify the undelrlying type in a forward declaration for plain enums (just like in the new "scoped" enums):
  enum MsgType : int; 

  class C
  {
  public:
    bool process(MsgType msg);
  };
Did you know that? I didn't.

At first I thought it would be a C++98 feature already** and was a little bit ashamed of myself - all that years doing C++98 and you didn't know that. Ooops! But then I looked it up and saw that it is a new C++11 feature. So, I'm still learning C++11 apparently.

Summary

All in all a nice post*, <praise> not simply reiterating some new syntax/feature, like so many other bloggers, but also giving some juicy technical bits away! </praise>

Update:
Recently, I saw this infornation on SO: "Microsoft's compiler has allowed specifying the underlying type of an enum as a proprietary extension since VS 2005."

--
* https://katecpp.wordpress.com/2015/12/28/enum-class/, all citations are from that post.

** that could be a single critique point for the above blogpost... but a small one!