|
|||||||||||
Technical Support On-Line Manuals Compiler User Guide ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Structures, unions, enumerations, and bitfields
14.10 Structures, unions, enumerations, and bitfieldsDescribes implementation-defined aspects of the ARM C compiler and C library relating to structures, unions, enumerations, and bitfields, as required by the ISO C standard. The ISO/IEC C standard requires the following implementation details to be documented for
structured data types:
UnionsWhen a member of a
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.EnumerationsAn object of type
enum is implemented in the smallest integral type
that contains the range of the enum . In C mode, and in C++ mode without
--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 :
Note
Implementing
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 .See the description of C language mappings in the Procedure Call Standard for the ARM®
Architecture specification for more information.
NoteCare must be taken when mixing translation units that have been compiled with and without the--enum_is_int option, and that share interfaces or data
structures.In strict C, enumerator values must be representable as
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 Such values are treated the same way as in C++, that is, they are treated as
unsigned
int , long long , or unsigned long
long . To ensure that out-of-range Warnings are reported, use the following command to change them into
Errors:
armcc --diag_error=66 ...
Padding and alignment of structuresThe following points apply to:
Structures can contain padding to ensure that fields are correctly aligned and that the structure
itself is correctly aligned. The following diagram shows an example of a conventional, nonpacked
structure. Bytes 1, 2, and 3 are padded to ensure correct field alignment. Bytes 11 and 12 are
padded to ensure correct structure alignment. The
sizeof() function returns the
size of the structure including padding.Figure 14-1 Conventional nonpacked structure example ![]() The compiler pads structures in one of the following ways, according to how the structure is
defined:
Use the
--remarks option to view the messages that are generated when the
compiler inserts padding in a struct .Structures with empty initializers are permitted in C++:
struct { int x; } X = { }; However, if you are compiling C, or compiling C++ with the
--cpp
and--c90 options, an error is generated.BitfieldsIn nonpacked structures, ARM Compiler allocates bitfields in containers. A container is a correctly aligned object of a declared type.
Bitfields are allocated so that the first field specified occupies the lowest-addressed bits of
the word, depending on configuration:
A bitfield container can be any of the integral types.
NoteIn strict 1990 ISO Standard C, the only types permitted for a bit field areint , signed int , and unsigned int . For
non-int bitfields,
the compiler displays an error.A plain bitfield, declared without either
signed or
unsigned qualifiers, is treated as unsigned . For
example, int x:10 allocates an unsigned integer of 10 bits.A bitfield is allocated to the first container of the correct type that has a sufficient number
of unallocated bits, for example:
struct X { int x:10; int y:20; }; The first declaration creates an integer container and allocates 10 bits to
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 .A bitfield is wholly contained within its container. A bitfield that does not fit in a container
is placed in the next container of the same type. For example, the declaration of
z
overflows the container if an additional bitfield is declared for the structure:struct X { int x:10; int y:20; int z:5; }; The compiler pads the remaining two bits for the first container and assigns a new integer
container for
z .Bitfield containers can overlap each other, for example:
struct X { int x:10; char y:2; }; The first declaration creates an integer container and allocates 10 bits to
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.Because the natural alignment of
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 .If
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; }; Figure 14-2 Bitfield allocation 1 ![]() NoteThe same basic rules apply to bitfield declarations with different container types. For example,
adding an
int bitfield to the example structure gives:struct X { int x:10; char y:8; int z:5; } The compiler allocates an
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:Figure 14-3 Bitfield allocation 2 ![]() You can explicitly pad a bitfield container by declaring an unnamed bitfield of size zero. A
bitfield of zero size fills the container up to the end if the container is not empty. A subsequent
bitfield declaration starts a new empty container.
NoteAs an optimization, the compiler might overwrite padding bits in a container with unspecified values when a bitfield is written. This does not affect normal usage of bitfields. | ||||||||||
|
Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.