Enum variable default value?

55,757

The program has Undefined Behavior. The value of enummy is indeterminate. Conceptually there is no difference between your code and the following code:

int main() {
   int i;          //indeterminate value
   std::cout << i; //undefined behavior
};

If you had defined your variable at namespace scope, it would be value initialized to 0.

enum SomeEnum {  
    EValue1 = 1,  
    EValue2 = 4,  
};
SomeEnum e; // e is 0
int i;      // i is 0

int main()
{
    cout << e << " " << i; //prints 0 0 
}

Don't be surprised that e can have values different from any of SomeEnum's enumerator values. Each enumeration type has an underlying integral type(such as int, short, or long) and the set of possible values of an object of that enumeration type is the set of values that the underlying integral type has. Enum is just a way to conveniently name some of the values and create a new type, but you don't restrict the values of your enumeration by the set of the enumerators' values.

Update: Some quotes backing me:

To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

Note that enumerations are scalar types.

To value-initialize an object of type T means:
— if T is a class type blah blah
— if T is a non-union class type blah blah
— if T is an array type, then blah blah — otherwise, the object is zero-initialized

So, we get into otherwise part. And namespace-scope objects are value-initialized

Share:
55,757
Haspemulator
Author by

Haspemulator

That was easy.

Updated on March 12, 2020

Comments

  • Haspemulator
    Haspemulator about 4 years

    The question is simple:

    #include <iostream>
    
    enum SomeEnum {  
        EValue1 = 1,  
        EValue2 = 4
    };
    
    int main() {
        SomeEnum enummy;
        std::cout << (int)enummy;
    }
    

    What will be the output?

    Note: This is not an interview, this is code inherited by me from previous developers. Streaming operator here is just for example, actual inherited code doesn't have it.

  • Haspemulator
    Haspemulator almost 13 years
    Thanks for info. Could you please point to specific paragraph in the C++ standard?
  • Tony Delroy
    Tony Delroy almost 13 years
    @Implicit in the last part of the answer is the fact that unless the user defines their own streaming operator for the enumeration, the default streaming for integral types is used after a conversion. So, even if e is set to EValue1, "1" will be printed and not "EValue1". You are allowed to create your own std::ostream& operator<<(std::ostream&, SomeEnum) function though.
  • Tony Delroy
    Tony Delroy almost 13 years
    @Haspemulator: Armen's explanation implicitly or explicitly covers many things: reading from uninitialised variables, initialisation of statics, implicit Standard conversion of enumerations to integral values.... IMHO, it's not reasonable to expect him to identify the relevant parts of the Standard for all of these, and you need to spend some time reading about the basics of C++.
  • Haspemulator
    Haspemulator almost 13 years
    @Tony: yes, I understand. I've written this comment when Armen's answer consisted from just one sentence. :)
  • David Hammen
    David Hammen almost 13 years
    @Haspemulator: I suspect Amen's original answer was "The program has Undefined Behavior." That should have been enough, shouldn't it? Don't invoke undefined behavior. If you do invoke undefined behavior, don't ask what the response will be. The response to undefined behavior is undefined.
  • Haspemulator
    Haspemulator almost 13 years
    @David Hammen: Yes, you're right, that was the original answer. But as far as I know, in C++ standard all the cases of undefined behavior are explicitly defined. I wanted only to read something official about it, and I thought that it would make the answer a little bit better (though it is good in its current state).
  • Armen Tsirunyan
    Armen Tsirunyan almost 13 years
    @Haspemulator: Oh, no, it's not true that all cases of UB are explicitly mentioned. There is a special clause that says that all behavior that isn't explicitly defined is implicitly undefined! And my original answer was one sentence longer :)
  • Haspemulator
    Haspemulator almost 13 years
    @Armen: thanks for clarification, I was not aware of that clause (actually, I have to admit that I've not read C++ standard as whole, only partially). I just saw that some cases of UB are specially mentioned there, and have made a false assumption spreading this fact to all such cases.
  • David Hammen
    David Hammen almost 13 years
    In fact, this particular case is explicitly mentioned: ISO/IEC 14882:2003(E) section 4.1, Lvalue-to-rvalue conversion, states that "if the object is uninitialized, a program that necessitates this conversion has undefined behavior."
  • legends2k
    legends2k about 10 years
    @ArmenTsirunyan: +1 for Enum is just a way to conveniently name some of the values and create a new type, but you don't restrict the values of your enumeration by the set of the enumerators' values.
  • Albert
    Albert over 6 years
    I think that the storage class also matters for the default value. As in your case the variables e and i are both global and will be stored in uninitialized part of data segment (bss) and hence the variable has 0 value.