gpt4 book ai didi

c++ - 是否有 C++ 位域的可移植替代品

转载 作者:IT老高 更新时间:2023-10-28 22:04:08 25 4
gpt4 key购买 nike

在很多情况下(尤其是在低级编程中),数据的二进制布局很重要。例如:硬件/驱动程序操作、网络协议(protocol)等。

在 C++ 中,我可以使用 char* 和按位运算(掩码和移位)读取/写入任意二进制结构,但这很乏味且容易出错。显然,我试图限制这些操作的范围,并将它们封装在更高级别的 API 中,但这仍然很痛苦。

C++ bitfields似乎为这个问题提供了一个对开发人员友好的解决方案,但不幸的是他们的存储是 implementation specific .

NathanOliver 提到了 std::bitset,它基本上允许您使用一个不错的 operator[] 访问整数的各个位,但缺少多位字段的访问器。

使用元编程和/或宏,可以在库中抽象按位操作。因为我不想重新发明轮子,所以我正在寻找一个(最好是 STL 或 boost)库。

作为记录,我正在调查 DNS解析器,但问题及其解决方案应该是通用的。

编辑:简短回答:事实证明,bitfield 的存储在实践中是可靠的(即使标准没有强制要求),因为系统/网络库使用它们并产生使用主流编译器编译时表现良好的程序。

最佳答案

来自 C++14 标准(N3797 草案),第 9.6 节 [class.bit],第 1 段:

Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. — end note ]

虽然注释是非规范性的,但我知道的每个实现都使用两种布局之一:大端或小端位顺序。

注意:

  • 您必须手动指定填充。这意味着您必须知道类型的大小(例如,使用 <cstdint> )。
  • 您必须使用无符号类型。
  • 用于检测位顺序的预处理器宏依赖于实现。
  • 通常位序字节序与字节序字节序相同。我相信有一个编译器标志可以覆盖它,但我找不到它。

例如,查看 netinet/tcp.h和其他附近的标题。

由 OP 编辑​​:例如 tcp.h定义

struct
{
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
# if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t th_x2:4; /* (unused) */
u_int8_t th_off:4; /* data offset */
# endif
# if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t th_off:4; /* data offset */
u_int8_t th_x2:4; /* (unused) */
# endif
// ...
}

而且由于它适用于主流编译器,这意味着 bitset 的内存布局在实践中是可靠的。

编辑:

这是在一个字节序内可移植的:

struct Foo {
uint16_t x: 10;
uint16_t y: 6;
};

但这可能不是因为它跨越了一个 16 位单元:

struct Foo {
uint16_t x: 10;
uint16_t y: 12;
uint16_t z: 10;
};

这可能不是因为它有隐式填充:

struct Foo {
uint16_t x: 10;
};

关于c++ - 是否有 C++ 位域的可移植替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31726191/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com