假设我们有一个结构定义如下:
struct S_BF {
unsigned first_bit : 1;
unsigned second_bit : 1;
unsigned rest : 30;
}
以及指向S_BF
结构的指针:
struct S_BF* bf;
如果有变量:
unsigned int p = 0;
[如何使bf
指向p
,所以我们可以通过修改p
的位字段来修改它的值,例如,如果我们想将p
的值更改为2,我们可以这个:
bf->second_bit = 1;
想要用类型为unsigned p
的指针访问struct S_BF*
的位的问题是它违反了严格别名规则C11 Standard - §6.5 Expressions (p6,7)。该规则旨在防止通过使用指向另一种类型的指针来访问一种类型的对象。 (有各种例外,但是该规则的目的是防止指针的类型操纵)
[通过唯一指向unsigned
的指针访问struct S_BF
的位,以使其通过union
和struct S_BF
之间的unsigned
使这些位成为相同位的唯一符合标准的方法。您必须通过指向struct S_BF
的指针访问struct S_BF
的位,并通过并集使struct S_BF
和unsigned
相同,而不会违反字符串别名规则。一个简短的例子是:
#include <stdio.h>
struct S_BF { /* bitfield struct */
unsigned first_bit : 1;
unsigned second_bit : 1;
unsigned rest : 30;
};
union s2u { /* union bitfield struct/unsigned */
struct S_BF s;
unsigned u;
};
int main (void) {
union s2u s2u = { .u = 0 }; /* union initialized zero */
struct S_BF *bf = &s2u.s; /* pointer to bitfield */
unsigned sz = 32; /* no. of bits in unsigned */
bf->second_bit = 1; /* set second bit 1 */
bf->rest = 0x2aaaaaaa; /* alternating bits 1010101... */
while (sz--) /* loop sz times, using unsigned value in union */
putchar (s2u.u >> sz & 1 ? '1' : '0'); /* output bits */
putchar ('\n');
}
示例使用/输出
上面的示例将产生以下输出:
$ ./bin/bitfield_union
10101010101010101010101010101010