Structures, unions, enumerations, and bitfields in ARM C and C++
2021-02-06 05:18
标签:arch htm style messages nat show off written int Describes the implementation of the structured data types Structures, unions, enumerations, and bitfields in ARM C and C++ 标签:arch htm style messages nat show off written int 原文地址:https://www.cnblogs.com/qiyuexin/p/12784293.htmlStructures, unions, enumerations, and bitfields in ARM C and C++
Non-Confidential
ARM DUI0375E
ARM® Compiler v5.04 for µVision armcc User Guide
Version 5
Home > C and C++ Implementation Details > Structures, unions, enumerations, and bitfields in ARM C and C++
10.4 Structures, unions, enumerations, and bitfields in ARM C and C++
union
, enum
, and struct
. It also discusses structure padding and bitfield implementation.Unions
union
is accessed using a member of a different type, the resulting value can be predicted from the representation of the original type. No error is given.Enumerations
enum
is implemented in the smallest integral type that contains the range of the enum
.--enum_is_int
, if an enum
contains only positive enumerator values, the storage type of the enum
is the first unsigned type from the following list, according to the range of the enumerators in the enum
. In other modes, and in cases where an enum
contains any negative enumerator values, the storage type of the enum
is the first of the following, according to the range of the enumerators in the enum
:
unsigned char
if not using --enum_is_int
signed char
if not using --enum_is_int
unsigned short
if not using --enum_is_int
signed short
if not using --enum_is_int
signed int
unsigned int
except C with --strict
signed long long
except C with --strict
unsigned long long
except C with --strict
.Note
In ARM Compiler 4.1 and later, the storage type of the enum
being the first unsigned type from the list applies irrespective of mode.enum
in this way can reduce data size. The command-line option --enum_is_int
forces the underlying type of enum
to at least as wide as int
.Note
--enum_is_int
option, and that share interfaces or data structures.int
s. That is, they must be in the range -2147483648 to +2147483647, inclusive. A warning is issued for out-of-range enumerator values:#66: enumeration value is out of "int" range
unsigned int
, long long
, or unsigned long long
.armcc --diag_error=66 ...
Structures
sizeof()
function returns the size of the structure including padding.
static
or extern
are padded with zeros.malloc()
or auto
, are
padded with whatever is previously stored in those memory locations. You cannot
use memcmp()
to compare padded structures defined in this
way.--remarks
option to view the messages that are
generated when the compiler inserts padding in a struct
.struct
{
int x;
} X = { };
--cpp
and--c90
options, an error is generated.Packed structures
__packed
qualifier. Alternatively, you can use #pragma pack(
to make sure that any structures with unaligned data are packed. There is no command-line option to change the default packing of structures.n
)Bitfields
Note
int
, signed int
, and unsigned int
. For non-int
bitfields, the compiler displays an error.signed
or unsigned
qualifiers, is treated as unsigned
. For example, int x:10
allocates an unsigned integer of 10 bits.struct X
{
int x:10;
int y:20;
};
x
. At the second declaration, the compiler finds the existing integer container with a sufficient number of unallocated bits, and allocates y
in the same container as x
.z
overflows the container if an additional bitfield is declared for the structure:struct X
{
int x:10;
int y:20;
int z:5;
};
z
.struct X
{
int x:10;
char y:2;
};
x
. These 10 bits occupy the first byte and two bits of the second byte of the integer container. At the second declaration, the compiler checks for a container of type char
. There is no suitable container, so the compiler allocates a new correctly aligned char
container.char
is 1, the compiler searches for the first byte that contains a sufficient number of unallocated bits to completely contain the bitfield. In the example structure, the second byte of the int
container has two bits allocated to x
, and six bits unallocated. The compiler allocates a char
container starting at the second byte of the previous int
container, skips the first two bits that are allocated to x
, and allocates two bits to y
.y
is declared char y:8
, the compiler pads the second byte and allocates a new char
container to the third byte, because the bitfield cannot overflow its container. The following figure shows the bitfield allocation for the following example structure:struct X
{
int x:10;
char y:8;
};
Note
int
bitfield to the example structure gives:struct X
{
int x:10;
char y:8;
int z:5;
}
int
container starting at the same location as the int x:10
container and allocates a byte-aligned char
and 5-bit bitfield, as follows:Note
Bitfields in packed structures
8*sizeof(container-type)-1
bits.struct A { int z:17; }; // sizeof(A) = 4, alignment = 4
struct A { __packed int z:17; }; // sizeof(A) = 3, alignment = 1
__packed struct A { int z:17; }; // sizeof(A) = 3, alignment = 1
struct A { char y:1; int z:31; }; // sizeof(A) = 4, alignment = 4
struct A { char y:1; __packed int z:31; }; // sizeof(A) = 4, alignment = 1
__packed struct A { char y:1; int z:31; }; // sizeof(A) = 4, alignment = 1
struct A { char y:1; int z:32; }; // sizeof(A) = 8, alignment = 4
struct A { char y:1; __packed int z:32; }; // sizeof(A) = 5, alignment = 1
__packed struct A { char y:1; int z:32; }; // sizeof(A) = 5, alignment = 1
struct A { int x; char y:1; int z:31; }; // sizeof(A) = 8, alignment = 4
struct A { int x; char y:1; __packed int z:31; }; // sizeof(A) = 8, alignment = 4
__packed struct A { int x; char y:1; int z:31; }; // sizeof(A) = 8, alignment = 1
struct A { int x; char y:1; int z:32; }; // sizeof(A) = 12, alignment = 4 [1]
struct A { int x; char y:1; __packed int z:32; }; // sizeof(A) = 12, alignment = 4 [2]
__packed struct A { int x; char y:1; int z:32; }; // sizeof(A) = 9, alignment = 1
struct example1
{
int a : 8; /* 4-byte container at offset 0 */
__packed int b : 8; /* 1-byte container at offset 1 */
__packed int c : 24; /* 3-byte container at offset 2 */
}; /* Total size 8 (3 bytes tail padding) */;
struct example2
{
__packed int a : 8; /* 1-byte container at offset 0 */
__packed int b : 8; /* 1-byte container at offset 1 */
int c : 8; /* 4-byte container at offset 0 */
}; /* Total size 4 (No tail padding) */
struct example3
{
int a : 8; /* 4-byte container at offset 0 */
__packed int b : 32; /* 4-byte container at offset 1 */
__packed int c : 32; /* 4-byte container at offset 5 */
int d : 16; /* 4-byte container at offset 8 */
int e : 16; /* 4-byte container at offset 12 */
int f : 16; /* In previous container */
}; /* Total size 16 (No tail padding) */
Non-Confidential
ARM DUI0375E
Copyright © 2007, 2008, 2011, 2012, 2014 ARM. All rights reserved.
Home > C and C++ Implementation Details > Structures, unions, enumerations, and bitfields in ARM C and C++
struct X
{
int x:10;
char y:8;
int z:5;
}
文章标题:Structures, unions, enumerations, and bitfields in ARM C and C++
文章链接:http://soscw.com/index.php/essay/51627.html