【问题标题】:Can C++ structs have different alignments at different compilation times?C++ 结构可以在不同的编译时间有不同的对齐方式吗?
【发布时间】: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 向量中。该结构有很多,但其他一切都只是普通的整数和浮点数,所以这就是问题所在。我该如何解决?
  • 找出它们最终不同的原因,确保所有翻译单元的构建配置一致。

标签: c++ struct compilation alignment padding


【解决方案1】:

问题是编译问题。由于未知原因,目标文件无法编译,因此链接器正在查找旧目标文件并针对该文件进行链接。由于该目标文件是由旧的源代码制成的,因此该结构在代码的不同部分不再具有相同的对齐方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2021-01-29
    • 2022-08-04
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多