简体   繁体   English

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

[英]Does accessing the 4 bytes of a float break C++ aliasing rules

I need to read the binary content of a file and turn the extracted bytes into single precision floating point numbers.我需要读取文件的二进制内容并将提取的字节转换为单精度浮点数。 How to do this has already been asked here .此处已询问如何执行此操作。 That question does have proper answers but I'm wondering whether a particular answer is actually valid C++ code.这个问题确实有正确的答案,但我想知道一个特定的答案是否真的有效 C++ 代码。

That answer gives the following code:该答案给出了以下代码:

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;
}

Is this actually valid C++ code?这实际上是有效的 C++ 代码吗? I'm not sure whether it violates any aliasing rules.我不确定它是否违反任何别名规则。

Note that I'm targeting platforms with big endian where a float is guaranteed to be at least 32 bits long.请注意,我针对的是具有大端字节序的平台,其中保证浮点数至少为 32 位长。

Is this actually valid C++ code?这实际上是有效的 C++ 代码吗?

Potentially yes.可能是的。 It has some pre-conditions:它有一些先决条件:

  • std::uint8_t must be an alias of unsigned char std::uint8_t必须是unsigned char的别名
  • sizeof(float) must be 4 sizeof(float)必须为 4
  • bytes + 3 mustn't overflow a buffer. bytes + 3不能溢出缓冲区。

You can add a checks to ensure safe failure to compile if the first two don't hold:如果前两个不成立,您可以添加检查以确保安全编译失败:

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 is excempted of such restrictions. unsigned char不受此类限制。 std::uint8_t , if it is defined, is in practice an alias of unsigned char , in which case the shown program is well defined. std::uint8_t如果已定义,实际上是unsigned char的别名,在这种情况下,显示的程序定义明确。 Technically that's not guaranteed by the rules, but the above check will handle the theoretical case where that doesn't apply.从技术上讲,规则并不能保证这一点,但上述检查将处理不适用的理论情况。


float is guaranteed to be at least 32 bits long. float 保证至少有32 位长。

It must be exactly 32 bits long for the code to work.代码必须恰好是 32 位长才能工作。 It must also have exactly the same bit-level format as was on the system where the float was serialised.它还必须具有与序列化浮点数的系统上完全相同的位级格式。 If it's standard IEE-754 single precision on both ends then you're good;如果它的两端都是标准的 IEE-754 单精度,那么你很好; otherwise all bets are off.否则所有的赌注都没有了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM