c-无法获取位字段的地址

c-无法获取位字段的地址,c,pointers,syntax-error,bit-fields,memory-address,C,Pointers,Syntax Error,Bit Fields,Memory Address,为什么不能获取位字段的地址? 如何创建指向位字段的指针 这是代码 不能有位字段的地址,因为最小的可寻址单元是字节(记住C中的字节不一定是8位宽) 您最好希望的是包含结构的地址 (C11)标准的相关部分是第6.5.3.2节地址和间接运算符(我的斜体): 一元&运算符的操作数应为函数指示符,即 []或一元*运算符,或指定非位字段且未使用寄存器存储类说明符声明的对象的左值 假设最小的可寻址性是一个字节,您可能会发现您的位文件压缩如下: Addr\Bit 7 6 5 4 3 2

为什么不能获取位字段的地址?

如何创建指向位字段的指针

这是代码


不能有位字段的地址,因为最小的可寻址单元是字节(记住C中的字节不一定是8位宽)

您最好希望的是包含结构的地址

(C11)标准的相关部分是第6.5.3.2节地址和间接运算符(我的斜体):

一元
&
运算符的操作数应为函数指示符,即
[]
或一元
*
运算符,或指定非位字段且未使用寄存器存储类说明符声明的对象的
左值

假设最小的可寻址性是一个字节,您可能会发现您的位文件压缩如下:

Addr\Bit   7   6   5   4   3   2   1   0
00001234 | a | b | c | d | ? | ? | ? | ? |
00001235 |   |   |   |   |   |   |   |   |
您可以看到,所有这些位文件的地址实际上都是相同的,因此它实际上没有那么有用


对于操作位文件,您实际上应该直接访问它们,并让编译器对它们进行排序。即使使用位运算符也不能保证有效,除非您知道编译器如何在内存中布局它们。

地址必须是整数字节数,但位字段不必是整数字节数,因此地址运算符
&
不能与它们一起使用。当然,如果您真的想处理位字段的地址,您可以使用封闭结构的地址,并进行一些位操作。

位字段成员(通常)小于指针允许的粒度,即
字符的粒度(根据char
的定义,顺便说一句,char的长度至少为8位)。因此,常规指针不会剪切它

此外,还不清楚指向位字段成员的指针的类型,因为要存储/检索这样的成员,编译器必须确切知道它在位字段中的位置(并且没有“常规”指针类型可以携带这样的信息)

最后,这几乎不是一个要求的功能(首先不经常看到位字段);位字段用于紧凑地存储信息或构建标志的压缩表示(例如写入硬件端口),很少需要指向其中单个字段的指针,如果需要,您可以始终求助于常规的
struct
,并在最后一刻转换为位字段


由于所有这些原因,标准规定位域成员不可寻址,句号。可以克服这些障碍(例如,通过定义存储访问位域成员所需的所有信息的特殊指针类型),但这将是语言中另一个没有人使用的过于复杂的黑暗角落。

类似地,如果您只想处理单个字节,您可以这样做:

union PAIR  {
    struct { uint8_t l, h; } b;
    uint16_t w;
};

PAIR ax;
现在,您可以访问诸如&ax.w、&ax.b.l或&ax.b.h等片段的指针 请注意,这仍然不允许您指向单个位,请参阅前面的解释


编辑:修复示例

您无法打印位字段的地址,但可以将其分配给所需大小类型(从一位内存转换为2字节(对于整数类型,大小取决于编译器)内存)的某个局部变量,该变量可用于打印地址

无符号整数x=pipe.a;
printf(“x=%d”,&x)

你不能做一个指向位域的指针。它的类型是什么?@melpomene:hmm,为什么这才是真正的问题?如果我们说它会有指向无符号int的
指针呢?就像上面显示的代码一样…但是为什么不能做指向位域的指针呢?CPU应该如何访问它?你读过关于对齐的内容吗?你是对的-它不能,而且没有“常规”指针类型可以携带这样的信息“最终有人指出它不仅仅是”标准说。。。“实际上,在64位系统上,指针可以引用特定位。截至2017年,指针仅使用64位中的48位,Intel计划在不久的将来展开一个使用56位的硬件。因此,您可以使用最高的3位对字节内的位偏移量进行编码,并通过一些位操作对字节内的所有内容进行编码(void*)在C++中,你可以用C风格或模板中的预编译器宏来完成它。但是,没有必要支持标准中的这种奇怪特性。需要它的人可以实现ITP。S。在64位架构中,滥用指针内的空闲位是很常见的。Linux使用其中的一些来编码指针+错误代码。ingle(void*)作为结构的构造函数的返回值。内核板内存分配器也使用指针的最高有效8位来存储额外的数据。但同样,这是对类型而不是standard@DanielHsH另一种使用指针未使用位的情况是Haskell语言(和其他类似的函数式语言)其中位用于跟踪处理时使用的构造函数。这种做法称为。这只是关于类型双关的未定义行为。联合欺骗编译器,使其可能不会与您发生冲突。但无论如何,访问位的地址是不可能的,因为按标准,字节是smalles可寻址单元然而,这个技巧在许多模拟器中使用,而且它们的功能似乎与此相反。例如,mame,你可以在这里看到:你知道你的链接不支持你的答案,是吗?当你以这种方式去区分它时,未定义的行为就会出现。而不是它本身的结构。在你的链接中,ti在ifdefs中用于endian安全泰,什么是绝对合法的。你建议用它来解引用。什么是非法的,结果也没有用。仅供你参考:ISO/IEC:9899(C99 TC3)在第102页有关于位字段的foornote 106,它说:“
union PAIR  {
    struct { uint8_t l, h; } b;
    uint16_t w;
};

PAIR ax;