3

I have a class defined as follows

struct X {
    X() : data() {}

    int data;

    enum class Zzz : int { zero, one, two };
    Zzz  zzz;
};
...
X xval;

What is the value of xval.zzz - is undefined or X::Zzz.zero ? I know it will be undefined for regular enums and I am wondering whether typed enums behave differently.

uuu777
  • 765
  • 4
  • 21
  • Possible duplicate of [uninitialized enum variable value](https://stackoverflow.com/questions/17699949/uninitialized-enum-variable-value) – underscore_d Jul 07 '17 at 13:42
  • Why did you think it would be zero? `enum`s are no different from other basic types in not having any valid value if left uninitialised. This question lacks basic research IMO. – underscore_d Jul 07 '17 at 13:43
  • @underscore_d: I find that to be harsh. An `enum class` makes a good attempt to restrict the values to the explicit enumerations. There is an argument then that some sort of initialisation ought to occur automatically. – Bathsheba Jul 07 '17 at 13:50
  • @Bathsheba I see what you mean, but that argument is only really made by those who don't yet know about C++'s policy of 'you don't pay for what you don't use'. That is: the compiler doesn't & shouldn't force-initialise your basic types to some default if you might just change them to something else later (tracking whether you do & only forcing a default if you don't seems not worth it). Given that OP asked 'is it undefined?', they seem to know C++ doesn't force default initialisation for basic types; to me it follows that it wouldn't do so for `enum` as that's just an `int` beneath as you said – underscore_d Jul 07 '17 at 13:53
  • 2
    @underscore_d: Yes you make some fair points but this question is IMHO at least superior to the regex / floating point tosh that litters this site. – Bathsheba Jul 07 '17 at 13:54
  • 1
    @underscore_d - 'zero' has underlying value of 0 and it will be the result of an explicit call to default constructor 'zzz()' in initialization list. So, it is very plausible to guess that it will be also a value an implicit call to to the same constructor. We all know that there are no implicit calls for regular enums and I was wondering whether it is the same for typed enums. – uuu777 Jul 07 '17 at 14:49
  • also kind of an indirect duplicate of: [What are global strongly-typed enums initialized to by default in C++?](https://stackoverflow.com/questions/25528245/what-are-global-strongly-typed-enums-initialized-to-by-default-in-c) – underscore_d Jul 10 '17 at 09:32

1 Answers1

3

It's uninitialised.

Since the backing type is an int and that can contain a trap representation, the reading of xval.zzz prior to initialisation is undefined. (Out of interest, if the backing type was a char, unsigned char, or signed char, then the behaviour would be merely implementation defined.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Note that if you change `{ zero, one, two }` to `{ zero = 1, one, two }` there is no output on ideone.com. That suggests to me that the initialisation is to 0, rather than to the value of the first enumeration member. See https://ideone.com/b9mvD1 – Bathsheba Jul 07 '17 at 13:52
  • 3
    @Caribou It is not "value initialized". The behaviour is undefined. What one compiler happens to do for you is completely meaningless. In that case, that compiler just coincidentally allocated the variable in memory whose (un)initial(ised) contents coincidentally represents 0. – underscore_d Jul 07 '17 at 13:55
  • @underscore_d: Absolutely. – Bathsheba Jul 07 '17 at 13:56
  • 1
    Besides, even if it happens to represent 0, the mere act of reading that memory is UB, so philisophically it invalidates the rest of the program (even if technically, most compilers will not punish you for doing so). – underscore_d Jul 07 '17 at 14:02
  • 1
    @underscore_d Well, you're right. It looks like uninitialised ints on ideone are actually 0 (at least a few I tried). Thank's for clarification. – Outshined Jul 07 '17 at 14:39
  • @Caribou Various compilers specifically initialise memory in debug mode (something that seems like more hindrance than help to me, since it encourages wrong assumptions), and even if they don't or you compile in release mode, the memory might incidentally be 0 or some other relatively predictable pattern. This can't be relied on in any form, however. – underscore_d Jul 07 '17 at 14:41
  • BTW: if we want know the answer from running a code snippet we need define a class specific new operator that will fill allocated memory with 0xff first and then do second try with 0xfe. – uuu777 Sep 05 '18 at 12:52