详解数据模型(LP32 ILP32 LP64 LLP64 ILP64 )中的不同数据类型

不同数据模型下,各数据类型的位数:

Type \ Model LP32 IPL32 LP64 ILP64 LLP64
char 8 8 8 8 8
short 16 16 16 16 16
int 16 32 32 64 32
long 32 32 64 64 32
long long 64 64 64 64 64
pointer 32 32 64 64 64


在这张表中,LP32和ILP32是32位平台上的字长模型,LP64,ILP64,LLP64是64位平台上的字长模型。

LP32指long和pointer是32位的,

ILP32指int,long和pointer是32位的,

LP64指long和pointer是64位,

ILP64指int,long,pointer是64位,

LLP64指long long和pointer是64位的。

常见32位环境一般仅涉及"ILP32"数据模型;而64位环境则使用不同的数据模型。现今所有64位的类Unix平台均使用LP64数据模型,而64位Windows使用LLP64数据模型。

以上 3 个 64 位模型(LP64、LLP64 和 ILP64)之间的区别在于非浮点数据类型。当一个或多个 C 数据类型的宽度从一种模型变换成另外一种模型时,应用程序可能会受到很多方面的影响。这些影响主要可以分为两类:

  • 数据对象的大小。编译器按照自然边界对数据类型进行对齐;换而言之,32 位的数据类型在 64 位系统上要按照 32 位边界进行对齐,而 64 位的数据类型在 64 位系统上则要按照 64 位边界进行对齐。这意味着诸如结构或联合之类的数据对象的大小在 32 位和 64 位系统上是不同的。
     
  • 基本数据类型的大小。通常关于基本数据类型之间关系的假设在 64 位数据模型上都已经无效了。依赖于这些关系的应用程序在 64 位平台上编译也会失败。例如,sizeof (int) = sizeof (long) = sizeof (pointer) 的假设对于 ILP32 数据模型有效,但是对于其他数据模型就无效了。

总之,编译器要按照自然边界对数据类型进行对齐,这意味着编译器会进行 “填充”,从而强制进行这种方式的对齐,就像是在 C 结构和联合中所做的一样。结构或联合的成员是根据最宽的成员进行对齐的。

 数据类型转换原则:

结构体对齐,默认对齐原则:

1.数据类型对齐值:
        char型数据自身对齐值为1
        short为2,int、float为4,double为8(windows)
        解释:
                char变量只要有一个空余的字节即可存放
                short要求首地址能被2整除,int、float、double同理
2.结构体的对齐值:
        其成员中自身对齐值最大的那个值。
        解释:
                结构体最终对齐按照数据成员中最长的类型的整数倍

指定对齐原则:

使用#pragma pack改变默认对齐原则
格式:
#pragma pack (value)时的指定对齐值value。
结构体最终对齐按照指定对齐值的整数倍
注意:
1.value只能是:1 2 4 8等
2.指定对齐值与数据类型对齐值相比取较小值
如:如果指定对齐值:
              设为1:则short、int、float等均为1
              设为2:则char仍为1,short为2,int 变为2

转自:数据模型(LP32 ILP32 LP64 LLP64 ILP64 )

猜你喜欢

转载自blog.csdn.net/Beast_Liu/article/details/85267414