SizeOf enumeration Type size detailed

Source: Internet
Author: User

The

to the point where the enum type begins with the C language is introduced into the language as a user-defined finite set constant, and is once the only way to define a compile-time constant in C + + (and then introduce a static integer constant in the Class). The
is based on a description of the type of enum to which the following issues are encountered:
1. What kind of type does an enum define?
2. What is the amount of memory space used as a user-defined type?
3. Is it true that using the enum type can be a boundary constraint for a finite set constant?
4. You may all know that the enum type and the int type have rules for implicit (automatic) conversions, so is it really possible to use an enum-type variable anywhere in place of a variable of type int?

 1. What kind of type is the type that the enum defines?
  in C + + it is well known that there are only two major types of classification: Pod type (note (1)) and class type. The type defined by the
 enum is actually a pod type, meaning that it participates in the implicit conversion rules of the pod type, so that the implicit conversion between the enum type and the int type appears.
  So that is, the type defined by the enum does not have a namespace qualifier (because it is not a class type), the constant quantum is defined as having the same visibility as the name space of the enum type, and a name conflict occurs because it does not have a name-qualifying capability.
  such as:
           struct Cetype
            {
                enum EType1 {e1, E2};
               enum EType2 {e1, E2};
          };
       The above example appears E1, E2 name conflict compile-time error because the enumerator (E1, E2) is the name in the Cetype namespace. Also, the enumeration in reference to the Cetype must be done in such a way as cetype::e1, rather than cetype::etype1::e1 for reference.

Note (1) Pod type:
You can think of pod type as a kind of data type from outer space with green protective layer, pod means "Plain old data" (translator: if must be translated into Chinese, it is called "the" Complete and "" "How about".) This is the meaning of the POD type.
The exact definition is fairly rough (see C + + ISO standard), which basically means that the POD type contains raw data that is compatible with C.
For example, structs and integers are POD types, but classes with constructors or virtual functions are not.
POD types do not have virtual functions, base classes, user-defined constructors, copy constructs, assignment operators, or destructor functions.
To conceptualize POD types, you can copy them by copying their bits. In addition, the POD type can be uninitialized.

2. What is the amount of memory space used as a user-defined type?
The problem is the question of how much sizeof (EType1) equals the size of each user-defined enumeration type.
In most 32-bit compilers (e.g. VC + +, GCC, etc.) the size of an enumerated type is actually the size of a sizeof (int), should the size of the enumerated type really be the size of the int type?
Not really, in the C + + standard document (ISO14882),
The standard describes this: "The size of the enumeration type is the size of an integer that can hold the value of the maximum enumerator",
It is also noted in the standard: "The value of an enumerator in an enumeration type must be able to be expressed in an int type",
That is, the size of an enumerated type cannot exceed the size of the int type, but it must have the same size as the int type.
The above standard has made it clear that as long as the integer that can hold the value of the largest enumerator is OK, it can be char, short, and Int.
For example:
Enum EType1 {e1 = Char_max};
Enum EType2 {e2 = Shrt_max};
Enum EType3 {E3 =int_max};
The three enumerated types above can be represented by the memory space of char, short, and int, namely:
sizeof (EType1) = = sizeof (char);
sizeof (EType2) = = sizeof (short);
sizeof (EType3) = = sizeof (int);
So why compile the size of the three enumerated types above the 32-bit compiler to the size of the int type?
It is primarily based on the requirements of 32-bit data memory for its aspects, the mandatory requirements for alignment in some computer hardware environments (e.g. Sun SPARC),
Some of them are due to the fact that a full 32-bit CPU processing efficiency is very high (e.g., IA32).
So it's not easy to assume that the size of the enumerated type is the size of type int, and you might encounter a compiler that uses the above processing strategy to conserve memory.
3. Is it true that using the enum type can be a boundary constraint for a finite set constant?
First look at the following example:
Enum EType {e1 = 0, E2};
void Func1 (EType e)
{
if (E = = e1)
{
Do something
}
Do something because e!= e1 must e = = E2
}
void Func2 (EType e)
{
if (E = = e1)
{
Do something
}
else if (e = = E2)
{
Do something
}
}

Func1 (static_cast<etype> (2));
Func2 (Static_cast<etype> (-1));
The above code should clearly illustrate the case of such an exception, which would cause the function to take the wrong action when calling the FUNC1 function with an integer value of a range, and the second function might be better. He simply ignores values that are out of range.
This means that the type defined by the enumeration is not a truly strongly typed set of finite constants, and there is no difference between declaring the two function arguments as integer types. So in the future, be aware of the pitfalls of enumerated types in standard definitions.
(In fact, only the class type is the true strong type)

4. Can you really use a variable of type enum in place of a variable of type int.
With the above discussion, in fact, the variables and integral variables of the enumeration type have too much consistency and interchangeability, so it is possible to substitute the enumeration type in every place that can use the int type.
Not really, after all, an enumeration type is a type that can be distinguished at compile time.
At the same time, the 2nd Analysis enumeration type does not necessarily have the same size as the int type, and these two differences determine that in some cases the enum type cannot be used instead of the int type.
Such as:
In the first case:
Enum EType {e1 = 0, e2,e3};
EType Val;
Std::cin >> Val;
In the second case:
Enum EType {e1 = 0, e2,e3};
EType Val;
STD::SCANF ("%d", &val);
The above two situations are basically the same type of problem, but they are not. The first scenario causes a compile-time error.
An error occurs because Std::cin does not define an overload >> operator for the corresponding enumerated type, which indicates that the enumeration type is an independent and discriminating type;
The second situation does not have any compile-time problems, but it may cause the scanf function stack to be corrupted and make the program run illegal.
It has been analyzed above that the size of an enumerated type variable is not necessarily the same as the int type, so we use%d to treat the enum type variable val as a 4-byte int variable and to stack the parameters.
Under some compilers sizeof (Val) is equal to 1 bytes, so the scanf function pushes the subsequent three-byte address in the Val variable address into the stack,
and assign it, perhaps the three-byte address of the Val variable will have no special meaning to be overwritten (for example, a byte-aligned empty address space).
May think that he will not be wrong, in fact, in the SCANF function call after the end of the stack cleanup,
This causes the scanf function to clean up too many address spaces, thereby destroying the point of the stack pointer of the perimeter function, which inevitably results in a program Run-time error.

There are so many drawbacks to enumeration types described above, so how can we have a type-safe enumeration type? In fact, there is a proposal for enumerating the scope issues in the latest draft C++0X standards, but the ultimate solution will be impossible to foresee, after all, for a wide range of languages like C + +, any additions, deletions and modifications of any feature must be carefully guarded.

Of course, we can use some circuitous methods to solve this problem (C + + can always give us a lot of surprises and surprises).

For example, we can place an enumeration value in a structure and use operator overloading to approximate the attributes of an enumeration:

struct FileAccess {
Enum __enum {
Read = 0x1,
Write = 0x2
};
__enum _value; enumeration value

FileAccess (int value = 0): _value ((__enum) value) {}
fileaccess& operator= (int value) {
This->_value = (__enum) value;
return *this;
}
operator int () const {
Return this->_value;
}
};

We can now use this enumeration type in the way we want it to:

FileAccess access = Fileaccess::read;

Also, because we provide a conversion operator to the int type, it can be used wherever an int is needed, such as a switch statement:

Switch (Access) {
Case Fileaccess::read:
Break
Case Fileaccess::write:
Break
}

Of course we don't want to hand-write this structure every time. By using macros, we can easily do this:

#define DECLARE_ENUM (E) \
struct E \
{ \
Public: \
E (int value = 0): _value ((__enum) value) {\
} \
e& operator= (int value) {\
This->_value = (__enum) value;\
return *this; \
} \
operator int () const {\
Return this->_value; \
} \
\
Enum __enum {

#define END_ENUM () \
}; \
\
Private: \
__enum _value; \
};

We can now define the preceding enumeration in the following manner, and it is no more complicated than writing an enum directly.

Declare_enum (FileAccess)
Read = 0x1,
Write = 0x2,
End_enum ()

Declare_enum (FileShare)
Read = 0x1,
Write = 0x2,
End_enum ()

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.