【发布时间】:2021-02-06 14:00:13
【问题描述】:
我有一些值要写入原始字节数组,在精确定义的位置,以通过网络发送它们。
//These are computed somewhere else in the program (and converted to little-endian regardless of platform):
using float32_t = float; static_assert(sizeof(float32_t) == 4);
uint32_t someInteger = 42;
float32_t someFloat = 4.2f;
bool someBoolean = true;
uint16_t someIndex = 42, someCRC1 = 42;
我的第一个解决方案有效并产生了正确的结果,但内存清理程序警告我有关未对齐的写入:
char* data = someBuffer.data(); //points directly into allocated raw bytes
(*reinterpret_cast<uint32_t *>(data )) = someInteger;
(*reinterpret_cast<bool *>(data + 4)) = someBoolean;
(*reinterpret_cast<float32_t*>(data + 5)) = someFloat; //unaligned
(*reinterpret_cast<uint16_t *>(data + 9)) = someIndex; //unaligned
(*reinterpret_cast<uint16_t *>(data + 11)) = someCRC; //unaligned
所以我想出了第二种解决方案,方法是重新排序一些值并插入一个 1 字节的缓冲区以在两者之间对齐。
char* data = someBuffer.data(); //points directly into allocated raw bytes
(*reinterpret_cast<uint32_t *>(data )) = someInteger;
(*reinterpret_cast<float32_t*>(data + 4)) = someFloat;
(*reinterpret_cast<bool *>(data + 8)) = someBoolean;
(*reinterpret_cast<char *>(data + 9)) = '\0'; //buffer for memory alignment
(*reinterpret_cast<uint16_t *>(data + 10)) = someIndex;
(*reinterpret_cast<uint16_t *>(data + 12)) = someCRC; //this has to be the last value!
但是我更希望有第一个排序并且没有对齐字节。 这可能独立于平台还是我必须依赖支持未对齐的商店指令?我听说使用std::memcpy 可能能够做到这一点,但我不确定如果这是真的,我将如何使用它。
【问题讨论】:
-
@EricPostpischil 这也适用于例如ARM 商店必须在哪里对齐?
-
它由 C++ 标准的规则定义。这意味着任何符合 C++ 的实现都必须正确实现它。
memcpy被定义为按字节复制数据,前提是源和目标不重叠。所以对齐是无关紧要的。它将字节从一个地方复制到另一个地方。如果编译器可以确定源对齐和目标对齐是令人满意的,它可以分别使用对齐加载和对齐存储指令。如果不能,它将酌情使用加载字节、存储字节和/或其他指令。
标签: c++ c++17 memory-alignment