sle*_*dog 14 c pointers syntax-error memory-address bit-fields
为什么不能取位域的地址?
如何制作指向位字段的指针?
这是代码......
struct bitfield {
unsigned int a: 1;
unsigned int b: 1;
unsigned int c: 1;
unsigned int d: 1;
};
int main(void)
{
struct bitfield pipe = {
.a = 1, .b = 0,
.c = 0, .d = 0
};
printf("%d %d %d %d\n", pipe.a,
pipe.b, pipe.c, pipe.d);
printf("%p\n", &pipe.a); /* OPPS HERE */
// error: cannot take address of bit-field ...
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*lia 29
位域成员(典型地)大于由指针所允许的粒度,这是的粒度较小的charS(由定义的char,其中的方式的任务是为8位长的至少).因此,常规指针不会削减它.
此外,还不清楚指向位域成员的指针的类型是什么,因为要存储/检索这样的成员,编译器必须确切地知道它在位域中的位置(并且没有"常规"指针类型可以携带此类信息).
最后,它几乎不是一个要求的功能(首先不会经常看到位域); bitfields用于紧凑地存储信息或构建标志的打包表示(例如写入硬件端口),很少需要指向它们的单个字段的指针- 如果需要,你总是可以求助于常规struct并在最后一刻转换为位域.
由于所有这些原因,标准表明位域成员不可寻址,周期.这可能可以克服这些障碍(例如,通过定义存储访问位域成员所需的所有信息专项指针类型),但它会是又没有人使用的语言的另一过于复杂阴暗的角落.
您不能拥有位字段的地址,因为最小的可寻址单位是一个字节(记住C中的字节可能不一定是8位宽).
您可能希望的最好的是包含结构的地址.
(C11)标准的相关部分是6.5.3.2 Address and indirection operators(我的斜体)部分:
一元运算
&符的操作数应该是函数指示符,[]一元或一元运算*符的结果 ,或者lvalue指定一个不是位字段且不用寄存器存储类说明符声明的对象.
鉴于最小的可寻址性是一个字节,你可能会发现你的bitfileds被压缩:
Addr\Bit 7 6 5 4 3 2 1 0
00001234 | a | b | c | d | ? | ? | ? | ? |
00001235 | | | | | | | | |
Run Code Online (Sandbox Code Playgroud)
你可以看到所有那些bitfileds的地址实际上是相同的,所以它并没有那么有用.
对于操作bitfileds,你真的应该直接访问它们并让编译器对它们进行排序.除非您知道编译器如何将它们放在内存中,否则即使使用按位运算符也不能保证工作.
| 归档时间: |
|
| 查看次数: |
17601 次 |
| 最近记录: |