sas*_*alm 9 c++ struct alignment
如果我有一个数组或一个指向数组的指针,那么将它重新解释为一个包含该数组的结构是否安全?
double *edges = ...; // Each edge is defined by 4 doubles in the array.
struct Edge { double vals[4]; };
Edge *asStruct = reinterpret_cast<Edge*>(edges);
std::sort(asStruct, asStruct + edgesCount, EdgeLengthComparator());
Run Code Online (Sandbox Code Playgroud)
特别是,sizeof(Edge) == sizeof(double)*4永远都是真的吗?它是否符合标准?如果没有,那么英特尔,AMD和ARM在实践中是否属实?你知道架构哪里不对吗?我已经在x86上测试了它,它在那里工作正常.
为什么我需要它:如果你想知道为什么我需要这样的东西,我认为它是一个可能的解决方案用std :: sort()按元素块排序
编辑:我发现有一个__attribute__((__packed__))GCC,至少可以保证GCC吗?MSVC有类似的选择吗?
\n\n\n有标准保证吗?
\n
正式来说,不;实际上,是的。最接近保证的是 C++11 9.2/20:
\n\n\n\n\n指向标准布局结构对象的指针,使用适当转换
\nreinterpret_cast指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。[ 注意:因此,标准布局结构对象内可能存在未命名的填充,但在其开头则不然,这是实现适当对齐所必需的。\xe2\x80\x94 尾注]
因此,强制转换将正确地将第一个数组元素重新解释为单个结构;但我不认为有正式的保证它不会期望结构之间有额外的填充。
\n\n\n\n\n如果不是,那么 Intel、AMD 和 ARM 的实际情况是否如此?
\n
至少在像您列出的主流架构上,在这种情况下不需要添加填充来对齐,也没有其他理由这样做;所以在实践中,这应该可行,但不能保证可移植性。
\n\n\n\n\n我发现有一个
\n__attribute__((__packed__))for GCC,这至少可以保证 GCC 可用吗?
是的。根据文档,此“指定用于表示类型的最小所需内存”,因此它将阻止在数组成员之后添加任何填充。
\n\n\n\n\nMSVC 有类似的选择吗?
\n
它有一个编译器标志 /Zp1和一个编译指示 #pragma pack(push, 1)(用于#pragma pack(pop)恢复默认对齐),但它们似乎没有提供您需要的保证;它们控制“存储第一个结构成员后的每个结构成员”的对齐方式,但没有提及整体结构大小。