zoukankan      html  css  js  c++  java
  • 为什么需要字节对齐?

    为什么需要字节对齐?

    计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。

    字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:

    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节(trailing padding)。

    结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,这个宏也在stddef.h中定义,如下:

    struct S2

    {

    int i;

    char c;

    };

    #define offsetof(s,m) (size_t)&(((s *)0)->m)

    例如,想要获得S2c的偏移量,方法为

    size_t pos = offsetof(S2, c);// pos等于4

    还有一个影响sizeof的重要参量,那便是编译器的 pack指令。它是用来调整结构体对齐方式的,不同编译器名称和用法略有不同,VC6中通过#pragma pack实现,也可以直接修改/Zp编译开关。

    #pragma pack的基本用法为:#pragma pack( n )n为字节对齐数,其取值为124816,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值,

    公式如下:

    offsetof( item ) = min( n, sizeof( item ) )

    再看示例:

    #pragma pack(push) // 将当前pack设置压栈保存

    #pragma pack(2) // 必须在结构体定义之前使用

    struct S1

    {

    char c;

    int i;

    };

    struct S3

    {

    char c1;

    S1 s;

    char c2;

    };

    #pragma pack(pop) // 恢复先前的pack设置

    还有一点要注意,“空结构体”(不含数据成员)的大小不为0,而是1。试想一个“不占空间”的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢于是,“空结构体”变量也得被存储,这样编译器也就只能为其分配一个字节的空间用于占位了。

    struct S5 { };

    原文:

    http://baike.baidu.com/view/1356720.htm

  • 相关阅读:
    杂七杂八注意
    数字和表达式
    小总结
    层级定位
    webdriver对象定位方法
    自动化测试第一季-selenium + python(环境搭建与基础代码解释)
    补基础—.—
    1-13 代理ARP和RARP
    Nginx/LVS/HAProxy负载均衡软件的优缺点详解
    分布式集群系统下的高可用session解决方案
  • 原文地址:https://www.cnblogs.com/mydomain/p/2774830.html
Copyright © 2011-2022 走看看