Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用字符数组将位字段打包为短整数?_C_Bit Fields_Bit Packing - Fatal编程技术网

C 如何使用字符数组将位字段打包为短整数?

C 如何使用字符数组将位字段打包为短整数?,c,bit-fields,bit-packing,C,Bit Fields,Bit Packing,在以下两种结构中 typedef struct _a { short a1:13 __attribute__((packed)); char a2[4] __attribute__((packed)); } a; typedef struct _b { short b1:10 __attribute__((packed)); short b2:10 __attribute__((packed)); short b3:12 __attribute__((

在以下两种结构中

typedef struct _a {
    short a1:13 __attribute__((packed));
    char a2[4]  __attribute__((packed));
} a;

typedef struct _b {
    short b1:10 __attribute__((packed));
    short b2:10 __attribute__((packed));
    short b3:12 __attribute__((packed));
} b;
结构b
中,我发现b2的位用b1填充,b3的位用b2填充。它最终产生4字节的值

我期待着结构a出现类似的行为,但我没有看到相同的情况。前2个字节被a1(未使用的5位)占用,后面4个字节被a2占用


这种行为是预期的吗?为什么我不能将字符[4]与short:13一起打包?有办法实现吗?

a2
不是一个位字段,因此它永远不会与
a1
放在一起。标准上说

存储在任何其他对象类型的非位字段对象中的值 由n×CHAR_位组成,其中n是该对象的大小 键入,以字节为单位。可以将值复制到类型为的对象中 未签名字符[n](例如,由memcpy);结果字节集为 调用值的对象表示形式


因此,这样的子对象必须是一个可寻址的单元,并且该规则没有例外。

a2
不是位字段,因此它永远不会与
a1
放在一起。标准上说

存储在任何其他对象类型的非位字段对象中的值 由n×CHAR_位组成,其中n是该对象的大小 键入,以字节为单位。可以将值复制到类型为的对象中 未签名字符[n](例如,由memcpy);结果字节集为 调用值的对象表示形式

因此,这样的子对象必须是一个可寻址的单元,并且该规则没有例外。

(太长了,不能作为注释,所以我把它作为一个答案)

若要将所有字段打包在一起,必须将数组替换为4个字段:

typedef struct _a {
    short a1:13 __attribute__((packed));
    char a2_0:8 __attribute__((packed));
    char a2_1:8 __attribute__((packed));
    char a2_2:8 __attribute__((packed));
    char a2_3:8 __attribute__((packed));
} a;
(太长了,不能作为评论,所以我把它作为回答)

若要将所有字段打包在一起,必须将数组替换为4个字段:

typedef struct _a {
    short a1:13 __attribute__((packed));
    char a2_0:8 __attribute__((packed));
    char a2_1:8 __attribute__((packed));
    char a2_2:8 __attribute__((packed));
    char a2_3:8 __attribute__((packed));
} a;

这不是有效的C代码,而是一些非标准的扩展。因此,除非你说明你使用的是哪种编译器,否则没有人能回答你的问题?我在一个标准的linux机器上,使用的是gcc(gcc)4.1.2 20071124(Red Hat 4.1.2-42)。@badman
\uu_属性(打包))
不是标准的C。这不是有效的C代码,而是一些非标准的扩展。因此,除非你说明你使用的是哪种编译器,否则没有人能回答你的问题?我在一个标准的linux机器上使用gcc(gcc)4.1.2 20071124(Red Hat 4.1.2-42)。@badman
\uuuuuuu属性(打包))
不是标准的C。谢谢!你说这是不可能的,这是可以接受的,因为它是这样设计的。我正在努力理解原因。为什么子对象必须是可寻址单元有限制?编译器应该能够理解我的意图。听起来不太复杂。你知道为什么会有这样的限制吗?@badmad,很简单,一个类型应该在编译单元之间兼容,所有以相同顺序声明相同类型字段的类型都必须具有相同的行为。因此,编译器无法推断在任何其他编译单元中,这样的地址都不会被获取。类型的概念是定义接口。顺便说一句,您的第一个示例甚至要求地址必须可用。你把它定义为一个数组,在C语言中,使用这样一个组件的唯一合理的方法就是在隐式接受数组起始地址的表达式中使用它!谢谢!非常感谢。你说这是不可能的,这是可以接受的,因为它是这样设计的。我正在努力理解原因。为什么子对象必须是可寻址单元有限制?编译器应该能够理解我的意图。听起来不太复杂。你知道为什么会有这样的限制吗?@badmad,很简单,一个类型应该在编译单元之间兼容,所有以相同顺序声明相同类型字段的类型都必须具有相同的行为。因此,编译器无法推断在任何其他编译单元中,这样的地址都不会被获取。类型的概念是定义接口。顺便说一句,您的第一个示例甚至要求地址必须可用。你把它定义为一个数组,在C语言中,使用这样一个组件的唯一合理的方法就是在隐式接受数组起始地址的表达式中使用它!谢谢!对你有用吗?这对我不起作用。我收到和以前一样的警告。它们必须是位字段。这是我的观点,但我忘了!现在修好了,对你有用吗?这对我不起作用。我收到和以前一样的警告。它们必须是位字段。这是我的观点,但我忘了!现在修好了。