Table 4-9 Compiler storage of data objects by byte alignment

Type Bytes Alignment
char, bool, _Bool 1 Located at any byte address.
short, wchar_t 2 Located at any address that is evenly divisible by 2.
float, int, long, pointer
4 Located at an address that is evenly divisible by 4.
long long, double, long double
8 Located at an address that is evenly divisible by 8.

Unions

当使用不同类型的成员访问联合成员时,可以从原始类型的表示中预测结果值。没有错误。

Enumerations

枚举类型的一个对象是最小的整数类型包含枚举的范围内实现。

在C和C++中的模式,模式没有-- enum_is_int,如果枚举包含积极的枚举值,该枚举的存储类型是从下面的列表中的第一个符号类型,根据该枚举器枚举的范围。在其他模式,在这种情况下,一个枚举包含任何负面的枚举值,该枚举的存储类型是下列第一,根据该枚举数的范围在枚举:

  • 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.

在混合使用和不使用-enum_is_int选项编译的转换单元以及共享接口或数据结构时,必须注意。在严格C中,枚举数值必须表示为INT。也就是说,他们必须在范围内-2147483648到2147483647,包括在内。对超出范围的枚举数值发出警告:

#66: enumeration value is out of "int" range

Structures

结构可以包含填充,以确保字段正确对齐,并确保结构本身正确地对齐。下图显示了一个常规的、不打包的结构的示例。填充字节1、2和3以确保正确的字段对齐。填充字节11和12以确保正确的结构对齐。函数返回结构的大小,包括填充。

编译器根据结构的定义方式以下列方式之一对结构进行解析:

  • 定义为静态或外部结构的结构用零填充。
  • 堆栈或堆上的结构,如使用malloc()或AUTO定义的结构,将填充以前存储在这些内存位置中的内容。您不能使用memcmp()来比较以这种方式定义的填充结构。

Bitfields

在非打包结构中,ARM编译器在容器中分配位字段。容器是声明类型的对齐对象。分配Bitfield使指定的第一个字段占用单词中寻址最低的位,具体取决于配置:

小端(Little-endian):最低地址意味着最不重要。大端(Big-endian):最低地址意味着最重要。

在严格的1990 ISO标准C中,唯一允许使用位字段的类型是int、符号int和无符号int。对于非int位字段,编译器将显示一个错误。无符号或无符号限定符声明的普通位字段被视为无符号。例如,intx:10分配一个10位的无符号整数。位字段被分配给具有足够数量未分配位的正确类型的第一个容器,例如:

struct X
{
int x:;
int y:;
};

第一个声明创建一个整数容器,并将10位分配给x。在第二个声明中,编译器找到具有足够数量未分配位的现有整数容器,并在与x相同的容器中分配y。

位字段完全包含在其容器中。不适合于容器的位字段放置在相同类型的下一个容器中。例如,如果为结构声明了额外的位字段,则z的声明会溢出容器:

struct X
{
int x:;
int y:;
int z:;
};

编译器为第一个容器分配剩余的两位,并为z分配一个新的整数容器。Bitfield容器可以相互重叠,例如:

struct X
{
int x:;
char y:;
};

第一个声明创建一个整数容器,并将10位分配给x。这10位占用整数容器的第一个字节和第二个字节的两个位。在第二个声明中,编译器检查char类型的容器。没有合适的容器,因此编译器分配一个新的正确对齐的char容器。

由于CHAR的自然对齐是1,编译器会搜索包含足够数量未分配位的第一个字节,以完全包含位字段。在示例结构中,int容器的第二字节具有分配给x的两个比特,以及未分配的六个比特。编译器在前一个int容器的第二个字节开始分配一个字符容器,跳过分配给x的前两个位,并将两个位分配给y。

如果y被声明为char y:8,编译器会将第二个字节存储起来,并将一个新的char容器分配给第三个字节,因为位字段不能溢出它的容器。下图显示了以下示例结构的位字段分配:

struct X
{
int x:;
char y:;
};

相同的基本规则适用于具有不同容器类型的位字段声明。例如,向示例结构中添加int位字段会提供:

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 10-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.

Note

As 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.

Bitfields in packed structures

Packed bitfield containers, including all bitfield containers in
packed structures, have an alignment of 1. Therefore the maximum bit padding
inserted to align a packed bitfield container is 7 bits.
For an unpacked bitfield container, the maximum bit padding is
8*sizeof(container-type)-1 bits.
Tail-padding is always inserted into the structure as necessary to
ensure arrays of the structure will have their elements correctly aligned.
A packed bitfield container is only large enough (in bytes) to hold
the bitfield that declared it. Non-packed bitfield containers are the size of
their type.
The following examples illustrate these interactions.
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
Note that [1] and [2] are not identical; the location of z within the structure and the tail-padding differ.
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) */
 

union, enum, and struct, 以及结构填充和位字段实现。的更多相关文章

  1. 关于C与C++的struct,union,enum用法差异

    对着代码说话: #include <stdio.h> #include <stdlib.h> struct test { int abc; }; enum _enum {A,B ...

  2. struct ifreq结构体与ip,子网掩码,网关等信息

    总结一下,今天学习的关于通过socket,ioctl来获得ip,netmask等信息,其中很多内容参照了很多网上的信息,我会一一列出的 我用的这个函数,就是下面这个函数,其中的有一些全局变量,很好懂, ...

  3. union内嵌struct用法

      // union内嵌struct用法 // 众所周知,union为联合体,struct为结构体.下面根据实例谈谈用法   #include <stdio.h>   #include & ...

  4. struct termios结构体【转】

    本文转载自:http://blog.csdn.net/vevenlcf/article/details/51096122 一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步通 ...

  5. Linux串口—struct termios结构体【转】

    转自:https://blog.csdn.net/yemingzhu163/article/details/5897156 一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步 ...

  6. struct termios结构体详解

    一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步通信端口. 这个结构包含了至少下列成员:tcflag_t c_iflag;      /* 输入模式 */tcflag_t ...

  7. struct socket结构体详解

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://weiguozhihui.blog.51cto.com/3060615/15852 ...

  8. linux网络接口,struct ifreq struct ifconf结构

    网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...

  9. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

随机推荐

  1. CSS3布局篇(多列布局)

    我们通过学习 CSS3,能够创建多个列来对文本进行布局 ,就像报纸那样排版那样! 可以参考详细说明:http://www.w3school.com.cn/css3/css3_multiple_colu ...

  2. hive UDAF开发和运行全过程

    介绍 hive的用户自定义聚合函数(UDAF)是一个很好的功能,集成了先进的数据处理.hive有两种UDAF:简单和通用.顾名思义,简单的UDAF,写的相当简单的,但因为使用Java反射导致性能损失, ...

  3. mybatis的核心对象图解

  4. Hdu-4757 Tree(可持久化字典树+lca)

    题目链接:点这 我的github地址:点这     Problem Description   Zero and One are good friends who always have fun wi ...

  5. RabbitMQ 交换器、持久化

    一. 交换器 RabbitMQ交换器(Exchange)分为四种 direct fanout topic headers direct  默认的交换器类型,消息的RoutingKey与队列的bindi ...

  6. IDEA上传项目到SVN

    1.打开IDEA ,上面工具栏选择VCS 选择把项目交给SVN管理 2.选择SVN 3.选择SVN管理后可以看到项目变这个颜色 4.右键项目选择如下 5.点击绿色的+号,选择一个SVN仓库的地址,下面 ...

  7. 2019 牛客多校第六场 D Move

    题目链接:https://ac.nowcoder.com/acm/contest/886/D 题解摘自官方题解 题目大意 有 K 个体积相同的箱子,有 N 个体积相同或相异的物品,现要按照如下策略装箱 ...

  8. 小程序 webview踩坑

    很多功能是需要调用wx.confing的 wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开, ...

  9. Feign 系列(03)Feign 工作原理

    目录 Feign 系列(03)Feign 工作原理 1. Feign 是如何设计的 2. Feign 动态代理 2.1 ReflectiveFeign 构建 2.2 生成代理对象 2.3 Method ...

  10. ubuntu安装WPS替代office

    安装 1.下载地址:http://community.wps.cn/download/(去WPS官网下载) 下载第一个即可 2.执行安装命令: sudo dpkg -i wps-office_10.1 ...