Enum [tag] [: type] {enum-list} [declarator] in C ++ - is this legal?

I work with a custom enumerated type in C ++, but it does not have many values. I want to try to reduce the size that they take, and I heard that enum types are always integer by default . Then I came across an MSDN entry in C ++ enumerations and found the following syntax very interesting:

 enum [: type] {enum-list}; 

Of course, it compiled with what I wanted (VS2008) when I did the following:

 enum plane : unsigned char { xy, xz, yz }; 

Now you can see from my enumeration constants that I don’t need much in terms of space - the unsigned char type would be ideal for my purposes.

However, I must say that I have never seen this form used anywhere else on the Internet - most are not even aware of it. I am trying to make this code cross-platform (and possibly for use on embedded systems), so I did not want to wonder ... Is this the correct C ++ syntax or is it only supported by the MSVC compiler?

As an aside, if it's legitimate C ++, why is this “function" usually not documented?

+6
source share
3 answers

This is non-standard, but it is expected to become part of the C ++ 0x standard. For me, when I compile in Visual Studio 2005 with the maximum warning level set, I get the following warning:

warning C4480: non-standard extension used: specifying the base type for the test listing

From the Wikipedia Page for C ++ 0x :

In standard C ++, enumerations are not type safe. They are effective integers, even if the enumeration types are different. This allows a comparison of two enumeration values ​​of different types of enumerations. The only security that C ++ 03 provides is that an integer or value from one type of enumeration is not converted implicitly to another type of enumeration. In addition, the basic integral type is determined by the implementation; code that depends on the size of the enumeration, therefore unbearable. Finally, enumeration values ​​are tied to spanning scope. Thus, it is not possible for two separate censuses to have the same names for the participants.

In addition, C ++ 0x allows standard enumerations to provide an explicit definition of the scope, as well as a definition of the base type:

 enum Enum3 : unsigned long {Val1 = 1, Val2}; 
+7
source

As stated in 0A0D, the notation you use is non-standard in C ++ 03, but C ++ 11 will be accepted.

If this is not enough for you, you can explicitly specify the bit field width used for enum fields in the critical structures in which they are embedded. This approach is ugly - I mention if for completeness; if it were a good solution, then the notation above would not have been accepted for C ++ 11. One of the problems is that you rely on an optional compiler warning to detect too small bit fields to store possible values ​​and may have to manually view them as the enumeration values ​​change.

For instance:

 enum E { A, B, C }; struct X { E e1 : 2; E e2 : 2; E e3 : 2; E e4 : 2; }; 

Note: an enumeration may take up more bits than requested - in GCC 4.5.2 without explicit compiler options, sizeof(X) above is still 4 ....

+2
source

This is completely legal. Embedding a type in an object to save space, however, will not be effective without guaranteeing alignment. If you leave alignment by default, padding bytes will be added (depending on the architecture), usually to the four-word boundary.

0
source

Source: https://habr.com/ru/post/893026/


All Articles