【问题标题】:used #pragma pack in c but could not understand在c中使用#pragma pack但无法理解
【发布时间】:2012-07-29 15:08:27
【问题描述】:

我已经编写了使用#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) 有什么区别?

【问题讨论】:

  • 3 对于pragma pack 无效。看看here
  • 我想知道,当我写 #pragma pack(1) 时,它会设置第一位,然后从下一位开始设置第二位,如果我写 #pragma(2) ,有什么区别
  • 您不希望在#define 行的末尾使用分号。您可能也不希望#pragma 行末尾的分号。

标签: c


【解决方案1】:

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

有效值为124816,以this page为例。

【讨论】:

    【解决方案2】:

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

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

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

    请参阅MSDN pagehere 了解更多详情。

    另外,下面来自here的一些关于结构包装的信息

    什么是结构填料?

    有时必须避免结构成员之间的填充字节。例如,读取 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 个字节边界对齐。

    【讨论】:

    • 当我在我的代码中应用并检索答案时,#pragma pack(1) 和 #pragma pack(2) 有什么区别,由于 struct emp e 的大小,按位或字节发生了什么正在改变
    【解决方案3】:

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

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

    如果创建emp 的数组,如emp a[10],则sizeof(emp) 也是数组中每个元素之间的距离。这就是为什么编译器会将大小向上舍入到 #pragma pack 值的下一个倍数。

    【讨论】:

      猜你喜欢
      • 2015-06-20
      • 1970-01-01
      • 2018-01-29
      • 2016-04-28
      • 2010-12-04
      • 2013-09-29
      • 2016-01-15
      • 1970-01-01
      • 2014-05-10
      相关资源
      最近更新 更多