C++ 结构可以在不同的编译时间有不同的对齐方式吗?
Posted
技术标签:
【中文标题】C++ 结构可以在不同的编译时间有不同的对齐方式吗?【英文标题】:Can C++ structs have different alignments at different compilation times? 【发布时间】:2020-11-23 02:46:01 【问题描述】:我有一些代码在过去与glm
一起工作的低级别上工作。我将 glm
的所有用法切换为 Eigen
现在我观察到一个奇怪的行为,即同一个结构似乎在代码的不同点具有不同的对齐方式。
这是 gdb 在初始化后给我的:
(gdb) p sizeof(CellShadingInfo)
$1 = 240
(gdb)
现在让我们看看具体全局结构的构造:
const std::unordered_map<std::string, size_t> uniform_size_map =
"GuiTransform", sizeof(GuiTransform),
"UniformBufferObject", sizeof(UniformBufferObject),
"GuiVisualProperties", sizeof(GuiVisualProperties),
"PostProcessingEffects", sizeof(PostProcessingEffects),
"LineProperties", sizeof(LineProperties),
"PointInfo", sizeof(PointInfo),
"GaussianVisualization", sizeof(GaussianVisualization),
"ParticleUBO", sizeof(ParticleUBO),
"CameraInfo", sizeof(CameraInfo),
"MVPOnlyUbo", sizeof(MVPOnlyUbo),
"WireframeDebugInfo", sizeof(WireframeDebugInfo),
"CellShadingInfo", sizeof(CellShadingInfo),
"GaussianProperties", sizeof(GaussianProperties)
;
这是全局的,所以它的初始化代码会在 main 之前运行。但由于 LUP 已被定义为常量,因此其中的所有值都应该是最终值,从而防止意外覆盖。
但是根据gdb:
(gdb) p uniform_size_map
$2 = std::unordered_map with 13 elements = ["CellShadingInfo"] = 228, ["MVPOnlyUbo"] = 192, ["ParticleUBO"] = 16,
["GaussianVisualization"] = 48, ["PointInfo"] = 36, ["PostProcessingEffects"] = 8, ["GuiVisualProperties"] = 20,
["GaussianProperties"] = 8, ["CameraInfo"] = 12, ["UniformBufferObject"] = 192, ["WireframeDebugInfo"] = 16,
["LineProperties"] = 40, ["GuiTransform"] = 16
所以我唯一的解释是编译器在 preinit 方法与常规运行时的编译过程中使用了不同的对齐方式。然而,这听起来很荒谬。
【问题讨论】:
我的猜测是,CellShadingInfo
有几个不同的定义,或者在不同的命名空间中(没关系),或者在相同的命名空间中但在不同的翻译单元中(这违反了 ODR)。也许有一些成员被包含或排除,或者基于宏改变类型;并且不同的翻译单元使用定义的不同宏进行编译。
整个程序中只有一个 CellShadingInfo 声明(刚刚用 grep 检查),我正在使用的宏处理器的唯一用途是通过包含。这会导致问题吗?
嗯,它可能类似于struct CellShadingInfo SomeType x;
,其中SomeType
的定义因翻译单元而异。或者可能有一个数组,其边界由一个变化的常数定义。违反 ODR 的方式有很多种。
"SomeType 的定义因翻译单元而异" 我 100% 确定这发生在 Eigen 向量中。该结构有很多,但其他一切都只是普通的整数和浮点数,所以这就是问题所在。我该如何解决?
找出它们最终不同的原因,确保所有翻译单元的构建配置一致。
【参考方案1】:
问题是编译问题。由于未知原因,目标文件无法编译,因此链接器正在查找旧目标文件并针对该文件进行链接。由于该目标文件是由旧的源代码制成的,因此该结构在代码的不同部分不再具有相同的对齐方式。
【讨论】:
以上是关于C++ 结构可以在不同的编译时间有不同的对齐方式吗?的主要内容,如果未能解决你的问题,请参考以下文章