访问 float 的 4 个字节是否会破坏 C++ 别名规则
Does accessing the 4 bytes of a float break C++ aliasing rules
我需要读取文件的二进制内容并将提取的字节转换为单精度浮点数。已经有人问过如何做到这一点 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++ 代码吗?我不确定它是否违反任何别名规则。
请注意,我针对的是具有大端字节序的平台,其中保证浮点数至少为 32 位长。
Is this actually valid C++ code?
可能是的。它有一些 pre-conditions:
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 位。它还必须具有与 float 被序列化的系统上完全相同的 bit-level 格式。如果它的两端都是标准的 IEE-754 单精度,那么你很好;否则所有赌注均无效。
我需要读取文件的二进制内容并将提取的字节转换为单精度浮点数。已经有人问过如何做到这一点 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++ 代码吗?我不确定它是否违反任何别名规则。
请注意,我针对的是具有大端字节序的平台,其中保证浮点数至少为 32 位长。
Is this actually valid C++ code?
可能是的。它有一些 pre-conditions:
std::uint8_t
必须是unsigned char
的别名
sizeof(float)
必须是 4bytes + 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 位。它还必须具有与 float 被序列化的系统上完全相同的 bit-level 格式。如果它的两端都是标准的 IEE-754 单精度,那么你很好;否则所有赌注均无效。