访问浮点数的 4 个字节是否会中断 C++别名规则
我需要读取文件的二进制内容并将提取的字节转换为单精度浮点数。 此处已询问如何执行此操作。这个问题确实有正确的答案,但我想知道特定的答案是否实际上是有效的 C++ 代码。
这个答案给出了以下代码:
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 位长。
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.
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? 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可能是的。它有一些先决条件:
std::uint8_t
必须是unsigned char
的别名sizeof(float)
必须是 4字节+ 3
不得溢出缓冲区。如果前两个不成立,您可以添加检查以确保编译安全失败:
unsigned char
不受此类限制。std::uint8_t
(如果已定义)实际上是unsigned char
的别名,在这种情况下,显示的程序已明确定义。从技术上讲,规则并不能保证这一点,但上述检查将处理不适用的理论情况。它的长度必须恰好为 32 位,代码才能正常工作。它还必须具有与序列化浮点的系统上完全相同的位级格式。如果两端都是标准 IEE-754 单精度,那么就很好;否则一切皆废。
Potentially yes. It has some pre-conditions:
std::uint8_t
must be an alias ofunsigned char
sizeof(float)
must be 4bytes + 3
mustn't overflow a buffer.You can add a checks to ensure safe failure to compile if the first two don't hold:
unsigned char
is excempted of such restrictions.std::uint8_t
, if it is defined, is in practice an alias ofunsigned char
, in which case the shown program is well defined. Technically that's not guaranteed by the rules, but the above check will handle the theoretical case where that doesn't apply.It must be exactly 32 bits long for the code to work. 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; otherwise all bets are off.