c++ - 访问 float 的 4 个字节是否会破坏 C++ 别名规则

标签 c++ floating-point language-lawyer endianness single-precision

我需要读取文件的二进制内容并将提取的字节转换为单精度 float 。如何做到这一点已经被问到 here 。该问题确实有正确的答案,但我想知道特定答案是否实际上是有效的 C++ 代码。

That answer 给出以下代码:

float bytesToFloat(uint8_t *bytes, bool big_endian) {
    float f;
    uint8_t *f_ptr = (uint8_t *) &f;
    if (big_endian) {
        f_ptr[3] = bytes[0];
        f_ptr[2] = bytes[1];
        f_ptr[1] = bytes[2];
        f_ptr[0] = bytes[3];
    } else {
        f_ptr[3] = bytes[3];
        f_ptr[2] = bytes[2];
        f_ptr[1] = bytes[1];
        f_ptr[0] = bytes[0];
    }
    return f;
}

这实际上是有效的 C++ 代码吗?我不确定它是否违反任何别名规则。

请注意,我的目标是具有大端序的平台,其中 float 保证至少为 32 位长。

最佳答案

Is this actually valid C++ code?

可能是的。它有一些先决条件:

  • std::uint8_t 必须是 unsigned char
  • 的别名
  • sizeof(float) 必须为 4
  • bytes + 3 不能溢出缓冲区。

如果前两个不成立,您可以添加检查以确保安全无法编译:

static_assert(std::is_same_v<unsigned char, std::uint8_t>);
static_assert(sizeof(float) == 4);

I'm not sure whether it violates any aliasing rules.

unsigned char 不受此类限制。 std::uint8_t,如果已定义,实际上是 unsigned char 的别名,在这种情况下,显示的程序定义良好。从技术上讲,规则并不能保证这一点,但上述检查将处理不适用的理论情况。


float is guaranteed to be at least 32 bits long.

代码的长度必须恰好为 32 位才能正常工作。它还必须具有与浮点被序列化的系统上完全相同的位级格式。如果两端都是标准的 IEE-754 单精度,那么你很好;否则所有赌注都取消。

关于c++ - 访问 float 的 4 个字节是否会破坏 C++ 别名规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71226137/

相关文章:

perl - int() 递减一个整数

c++ - 如何引用多维指针?

c - 只要您永远不取消引用它,持有未对齐的指针是否定义明确?

c++ - 比较 std::string 和 C 样式字符串文字

c - 除以和随后与相同 float 的乘法

c++ - 新接触窗口应用程序的人应该学习 X、GTK+ 还是什么?

swift - 在 swift 中比 double 更精确

c++ - 是否允许编译器支持标准中已删除的功能?

c++ - 程序员需要 C++ 元模板知识吗?

c++ - 如何使 clang-format 将所有详细命名空间缩进一个