【问题标题】:bytes are swapped when pointer cast is done in C在 C 中完成指针转换时交换字节
【发布时间】:2013-09-24 22:11:54
【问题描述】:

我有一个“无符号短”数组,即 C 中的每个元素 16 位。我有两个“无符号短”值,它们应该以小端顺序写回数组中,这意味着最不重要的元素将首先出现。例如,如果我有以下值:

unsigned int val = 0x12345678;

它应该存储在我的数组中:

unsigned short buff[10];
buff[0] = 0x5678;
buff[1] = 0x1234;

我已经编写了一个代码来一次写入值,而不是提取 int 值的高低 16 位并分别编写它们,因为可能存在原子性问题。我的代码如下所示:

typedef unsigned int UINT32;
*((UINT32*)(buff)) = (value & 0xffff0000)  + (value & 0xffff);

令人惊讶的是,上面的代码可以正常工作,结果将是:

buff[0] is 0x5678;
buff[1] is 0x1234;

问题是,如图所示,我以大端顺序保存“无符号短”值,而不是我希望的小端。换句话说,当我将指针从“unsigned short*”转换为“unsigned int*”时,16 位元素会自动交换!有谁知道这里发生了什么以及为什么交换数据?

【问题讨论】:

  • 尖刻的回答是这样的类型双关语是未定义的行为。
  • 如果你在 LE 中编写它们,每个 short 的字节也应该被翻转。还是您所指的字节序只是概念性的而不是实际的?如果实际,0x12345678 的字节顺序应该是0x78 0x56 0x34 0x12
  • 顺便说一句:(value & 0xffff0000) + (value & 0xffff)value 相同,如果 value 是 32 位。
  • 确实 (value & 0xffff0000) + (value & 0xffff) 与 value 本身相同。我只是出于测试目的手动将它们分开。感谢您的提示。

标签: c pointers casting


【解决方案1】:

您的平台以小端格式表示数据,并且通过将 buff 转换为 (UINT32 *),您告诉编译器现在必须将 buff 解释为指向 unsigned int 的指针。说明

*((UINT32*)(buff)) = (value & 0xffff0000)  + (value & 0xffff);

只是说“将 (value & 0xffff0000) + (value & 0xffff) 写入这个无符号整数 (buff)”。这就是他所做的,他如何存储它不是你的事。您不应该访问低 16 位或高 16 位,因为它取决于平台,哪个先出现。

您所知道的是,如果您以 unsigned int 的形式访问 buff,您将获得与之前存储在那里相同的值,但假设任何特定的字节顺序是不安全的。

所以基本上你的代码有未定义的行为。

【讨论】:

  • 这是一个很好的答案。根据硬件类型交换字节,这里可能也是小端。谢谢。
  • 是的,从您发布的示例来看,它看起来像小端。 Intel x86 和 x86-64 系列处理器使用 little-endian 格式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2013-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
相关资源
最近更新 更多