结构和对齐方式的大小

时间:2019-06-22 03:58:08

标签: c++ g++

根据此post,结构的对齐方式是特定于实现的,这意味着不同的编译器将以不同的方式对齐结构中的成员,从而使整个编译器中的同一结构的大小不同。

但是,在此video中,发言者听起来好像以下结构在编译器中的大小必须分别为16和12:

#include <iostream>

struct C {
    uint64_t x;
    uint32_t y;
};

struct D {
    uint32_t x;
    uint32_t y;
    uint32_t z;
};

int main() {
    std::cout << sizeof(C) << std::endl;
    std::cout << sizeof(D) << std::endl;
}

他们确实是16岁和12岁。

为什么必须分别是16和12?不是16和16?

1 个答案:

答案 0 :(得分:1)

  

他们确实是16岁和12岁。

它们的大小如下:

  • 您使用的编译器(&选项)
  • 您的目标平台
  • 代码中没有与资格/包装相关的指令

对于您的视频,我想演讲者只是采用了给定的平台/工具链来发展自己的榜样。但是,一般来说,由于sizeof(T)与编译器/平台有关,因此std::atomic<T>::is_lock_free()也与编译器/平台有关。

示例

使用以下结构:

struct C {
    uint64_t x;
    uint32_t y;
};

不同的编译器和选项

目标平台

对齐/包装指令

为什么有这些区别?

编译器可以在结构/类的任何字段之后随意添加未使用的位/字节。这样做是出于性能方面的考虑:在某些平台上,读/写多字节int会更快,以验证某些对齐属性(通常是N字节{{1}的地址) }必须被int整除。

通常,C ++编译器在后台执行低级优化很方便。有时您希望对该功能进行更多控制(原因不详尽):

  • 序列化将由其他程序读取的数据时(保存到文件,发送到网络)。
  • 当内存使用比执行速度更重要时。
  • 在多核和多线程程序中,控制CPU cache line中有多少N可以限制内核之间的cache invalidations,从而提高执行速度。

这就是为什么编译器通常提供实用程序来控制它的原因。

TL; DR

对于给定的structsizeof(T)并没有任何东西。它取决于编译器/平台,您通常可以使用特定的编译器指令来覆盖它。