5

Or another way to phrase this would be: can the compiler assume that an instance of an enum can only hold values it is declared to hold and optimize based on that assumption?

enum MyType { A = 1, B = 2 };

const MyType C = static_cast<MyType>(3);

void fun(MyType m) {
    switch (m) {
        case A:
            // ...
            break;
        case B:
            // ...
            break;
        case C:
            // can this be optimized away?
    }
}
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • It's unclear what you're asking? Why should the `C` case be optimized away? I can't see a clear reasoning for that. – πάντα ῥεῖ Sep 02 '16 at 22:19
  • 4
    @πάνταῥεῖ because it's not covered in the list for `MyType`. `g++` at least warns on this `case value ‘3’ not in enumerated type 'MyType'` – Ryan Haining Sep 02 '16 at 22:21
  • @RyanHaining Surely that's the least of your problems if you do the `const MyType C = static_cast(value)`? Such as updating your resume and filing with the court for a legal name change so your co-workers can't shame you out of getting work as a programmer in the future? – kfsone Sep 02 '16 at 22:27
  • @kfsone I just need some duct tape for this one. I don't like it either. – Ryan Haining Sep 02 '16 at 22:29
  • 2
    What are you trying to do? If you're worried about it, why not cast `m` to be an `int`? This seems reasonable as you're already breaking the data type of `m` in this particular case. At least in this simple case, you could also just use `if`. I know this doesn't fully answer your question. It just sort of seems bad to hedge on what the compiler will optimize away in this particular case versus working around syntax that would take away that ambiguity. – Mobile Ben Sep 02 '16 at 22:37
  • 1
    `void fun(int m) { return m>2? doTheStuffFor(m): fun(static_cast(m); }` and replace all the calls where you might have the issue. You might also experiment with having a MyExtendedType. – lorro Sep 02 '16 at 22:40
  • @RyanHaining Remember duct tape is sticky and probably doesn't serve you well in the long term maintenance. – πάντα ῥεῖ Sep 02 '16 at 23:51
  • 3
    Um, this code is perfectly valid. An enumerated type can hold any value that fits in the bits needed for the enumerators. That lets you use an enumerated type as a bitfield, a deliberate decision in the language definition and compatible with years of C usage. – Pete Becker Sep 02 '16 at 23:53
  • @RyanHaining: Do you think it would be fair to close this as a duplicate of http://stackoverflow.com/a/4969304/87234? This question boils down to "is `C` a valid value of the enum or not"? (If not, the behavior is undefined and the compiler can do anything, include skipping the case or reformatting the hard drive; if so, the compiler must check it like any other valid value.) – GManNickG Sep 03 '16 at 01:21

1 Answers1

4

The compiler cannot optimize out undeclared enum values. The section on the language spec that talks about enumerators says

It is possible to define an enumeration that has values not defined by any of its enumerators.

so the enumeration is allowed to have values that are not explicitly specified in the enum declaration.

In addition, the section on bitmask types gives examples that utilize undefined enum values, specifically mentioning 0 as a valid flag value.

Since it is valid to have enum values that are not declared, the compiler cannot optimize out code that utilized them.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • 1
    Kind of correct. There are valid values that may not be in the enumerator list, this doesn't mean all integer values are valid values for the enum. See http://stackoverflow.com/a/4969304/87234 – GManNickG Sep 03 '16 at 01:20