零长度位域的实际使用
我对 C 不太确定,但 C++ 允许长度为 0 的未命名位字段。例如:
struct X
{
int : 0;
};
- 问题一:您能想到什么实际用途?
- 问题二:您知道什么实际用途(如果有) ?
编辑了ice-crime回答后的示例
编辑:好的,感谢当前的答案我现在知道理论目的了。但问题是关于实际用途的,所以它们仍然成立:)
I am not totally sure about C, but C++ allows unnamed bit-fields of 0 length. For example:
struct X
{
int : 0;
};
- Question one: What practical uses of this can you think of?
- Question two: What real-world practical uses (if any) are you aware of?
Edited the example after ice-crime's answer
Edit: OK, thanks to the current answers I now know the theoretical purpose. But the questions are about practical uses so they still hold :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您使用零长度位字段作为一种黑客方法,让编译器布局一个结构以满足某些外部要求,无论是另一个编译器还是体系结构的布局概念(跨平台数据结构,例如二进制文件格式) )或位级标准的要求(网络数据包或指令操作码)。
一个真实的例子是 NeXT 将 xnu 内核从 Motorola 68000 (m68k) 架构移植到 i386 架构。 NeXT 有一个可用的 m68k 版本的内核。当他们将其移植到 i386 时,他们发现 i386 的对齐要求与 m68k 的不同,m68k 机器和 i386 机器在 NeXT 供应商特定的 BOOTP 结构的布局上不一致。为了使 i386 结构布局与 m68k 一致,他们添加了一个长度为零的未命名位字段,以强制
NV1
结构/nv_U
联合进行 16 位对齐。以下是 Mac OS X 10.6.5 xnu 源代码中的相关部分:
You use a zero-length bitfield as a hacky way to get your compiler to lay out a structure to match some external requirement, be it another compiler's or architecture's notion of the layout (cross-platform data structures, such as in a binary file format) or a bit-level standard's requirements (network packets or instruction opcodes).
A real-world example is when NeXT ported the xnu kernel from the Motorola 68000 (m68k) architecture to the i386 architecture. NeXT had a working m68k version of their kernel. When they ported it to i386, they found that the i386's alignment requirements differed from the m68k's in such a way that an m68k machine and an i386 machine did not agree on the layout of the NeXT vendor-specific BOOTP structure. In order to make the i386 structure layout agree with the m68k, they added an unnamed bitfield of length zero to force the
NV1
structure/nv_U
union to be 16-bit aligned.Here are the relevant parts from the Mac OS X 10.6.5 xnu source code:
标准 (9.6/2) 仅允许 0 长度位字段作为特殊情况:
尽管我从未在实际代码中遇到过它,但此引用中描述了唯一的用途。
作为记录,我刚刚在 VS 2010 下尝试了以下代码:
我机器上的输出确实是:
4 - 8
。The standard (9.6/2) only allows 0 length bit-fields as a special case :
The only use is described in this quote, although I've never encountered it in practical code yet.
For the record, I just tried the following code under VS 2010 :
The output on my machine is indeed :
4 - 8
.是 C 中未定义的行为。
参见(强调我的):
(C11 具有相同的措辞。)
您可以使用带有
0
宽度,但如果结构中没有其他命名成员,则不会。例如:
顺便说一句,对于第二个声明,
gcc
使用-pedantic
发出诊断(C 标准不要求)。另一方面:
在 GNU C 中定义。例如,Linux 内核 (
include/linux/bug.h
) 使用它来在条件为 true 时使用以下宏强制编译错误:is undefined behavior in C.
See (emphasis mine):
(C11 has the same wording.)
You can use an unnamed bit-field with
0
width but not if there is no other named member in the structure.For example:
By the way for the second declaration,
gcc
issues a diagnostic (not required by the C Standard) with-pedantic
.On the other hand:
is defined in GNU C. It is used for example by the Linux kernel (
include/linux/bug.h
) to force a compilation error using the following macro if the condition is true:这是来自 MSDN 的,没有标记为 Microsoft Specific,所以我猜这是常见的 C++ 标准:
宽度为 0 的未命名位字段强制下一个位字段与下一个类型边界对齐,其中类型是成员的类型。
This is from MSDN and not marked as Microsoft Specific, so I guess this is common C++ standard:
An unnamed bit field of width 0 forces alignment of the next bit field to the next type boundary, where type is the type of the member.
C11 标准现在允许包含零长度位字段。这是 C 委员会草案 (N1570) 中的一个示例,我相信它说明了实际用法。
因此,在位域
c
和d
之间包含零长度位域允许同时修改b
和d
:出色地。The C11 standard now allows the inclusion of zero length bitfields. Here is an example from the C Committee draft (N1570), which I believe illustrates a practical usage.
So including the zero length bitfield in between the bitfields
c
andd
allows the concurrent modification ofb
andd
as well.