2

我已经使用#pragma 指令编写了一个代码来对齐,但我无法理解对齐是如何发生的。我在 ubuntu 上使用 gcc。

#include<stdio.h>

#define MALE 0;
#define FEMALE 1;
#define SINGLE 0;
#define MARRIED 1;
#pragma pack(3);

int main()
{
    struct emp
    {
        unsigned gender :1;
        unsigned mar:1;
        unsigned hobby:1;
        unsigned scheme :1;
    };
    struct emp e;
    e.gender=MALE;
    e.mar=SINGLE;
    e.hobby=1;
    e.scheme=1;
    printf("size of %d",sizeof(e));
    return 0;
}

当我使用#pragma pack as 1 时,size 为 1,#pragma pack as 2 size 为 2,3 为 4。

你能告诉我发生了什么吗?如果我不使用它仍然 4 来。

#pragma pack(1)那么和 和有什么区别#pragma pack(2)呢?

4

3 回答 3

3

3不是#pragma pack指令的有效参数。

例如,根据此页面,有效值为12、和。4816

于 2012-07-29T15:11:41.183 回答
0

`#pragma' 指令是 C 标准指定的方法,用于向编译器提供超出语言本身传达的信息的附加信息。

#pragmapack 指定结构、联合和类成员的打包对齐方式。

有效值为 1、2、4、8 和 16。成员的对齐方式将位于上述任何值的倍数或成员大小的倍数的边界上,以较小者为准。

有关更多详细信息,请参阅MSDN 页面此处

此外,下面还有一些关于结构包装的信息

什么是结构填料?

有时必须避免结构成员之间的填充字节。例如,读取 ELF 文件头或 BMP 或 JPEG 文件头的内容。我们需要定义一个类似于标题布局的结构并映射它。但是,在访问此类成员时应小心谨慎。通常,逐字节读取是避免未对齐异常的一种选择。性能会受到打击。

大多数编译器提供非标准扩展来关闭默认填充,如编译指示或命令行开关。有关更多详细信息,请参阅相应编译器的文档。

i want to know that when i write #pragma pack(1) it set first bits and atart second from next one what if i write #pragma(2) , whats the difference 

要回答这个问题,当您将#pragma 设置为 2 时,如果结构中的数据小于 2 个字节,则对齐方式保持不变。但是,如果它超过 2 个字节(比如一个 4 字节整数),它将被拆分并在 2 个字节边界处对齐。

于 2012-07-29T15:29:35.847 回答
0

#pragma pack(1)和之间的区别在于#pragma pack(2),在第一种情况下,您说您的结构可以从任何地址开始。

#pragma pack(2)你说起始地址必须能被 2 整除(偶数地址)。 编译器通过说结构的大小为 2 来执行此操作(通过用一些未使用的空间填充它)。

如果您创建一个 的数组emp,例如emp a[10]sizeof(emp)则 也是数组中每个元素之间的距离。这就是编译器将大小四舍五入到该#pragma pack值的下一个倍数的原因。

于 2012-07-29T15:58:53.163 回答