【问题标题】:Does Endian-ness affect the union members when they are integers?当联合成员是整数时,字节序会影响联合成员吗?
【发布时间】:2021-08-05 11:19:07
【问题描述】:
union Chunk
{
  struct { uint32_t index, total; } m_;
  uint64_t m_PlaceHolder;
} chunk;
chunk.m_.index = 1;
chunk.m_.total = 2;
SendOverTCPNetwork(chunk.m_PlaceHolder); // different platform OS will receive this

为 2 个整数设置联合成员,然后通过 TCP 网络发送一个(组合的)长整数,如上面伪代码所示。

问题:源机器和目标机器的字节序会影响chunk变量的值吗?

换句话说,我们会在另一边收到相同的值吗?

【问题讨论】:

  • 想象SendOverTCPNetwork() 对每个基本类型都进行了重载,以修复(以防万一)其参数的字节顺序,例如网络字节顺序。假设本地 LE 和 BE 通过 TCP,这不仅会改变 indextotal 的字节序,还会改变它们的顺序。
  • 我的建议是不要让网络 API 接受整数。你应该通过std::bytes 或chars。你应该有一个转换函数,负责用你的整数/结构中的数据填充byte[],并酌情使用位移位。这样,您就可以 100% 移植并独立于主机字节序。避开hton 和朋友。
  • 现在问题已被编辑,它是通过联合进行类型双关语,这仍然是错误的,但方式不同。无论如何,您都是通过网络发送数据,只需将对象地址转换为 char* 而不是使用一些中间类型。

标签: c++ cross-platform union long-integer endianness


【解决方案1】:

源机器和目标机器的字节序会影响块变量的值吗?

是的。字节序影响所有整数,即使它们是类的成员。 (当然signed charunsigned char 除外)。


SendOverTCPNetwork(m_PlaceHolder);

没有对象就不能访问非静态成员。示例程序格式不正确。

【讨论】:

  • 顺便说一句,我已经编辑了格式错误的伪代码。如果m_PlaceHolder 被序列化为带有 Google protobuf 之类的字符数组,是否会按原样接收这些值?
  • @iammilind 编辑的程序具有未定义的行为,因为您从工会的非活动成员读取。
  • 我的看法是,一旦我们将 indextotal 变量存储在结构中。它还存储在m_PlaceHolder 中,它是同一union 的一部分。最终这个 uint64 变量只会被序列化。
  • @iammilind 你不能那样做。只能从当前处于活动状态的联合成员中读取(有特殊情况可以读取非活动成员,但示例程序没有此类异常)。
  • 我明白了,根据this answer,“联合中的类型双关语”在 C 中是允许的,但在 C++ 中是不允许的,尽管像 GCC 这样的许多编译器都支持它。顺便说一句,这是否意味着我们必须使用位移来获得类似的结果?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
相关资源
最近更新 更多