【问题标题】:sizeof(struct) different for different compilerssizeof(struct) 对于不同的编译器不同
【发布时间】:2015-02-18 09:45:19
【问题描述】:

假设我有这样的代码:

#include <stdio.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
    typedef struct{
        uint16_t x : 9;
        uint8_t y : 7;
    } z;
    printf("sizeof(z) = %lu\n",sizeof(z));
}

我在 Mac (2) 上的 clang 有不同的结果,有人告诉我在 Windows 上它返回了 (3)。不确定我是否理解得很好,但我看到虽然第一个编译器将结构压缩为 9+7 = 16 位,但另一个使用 16 位 uint16_t 和 8 位 uint8_t。能给个建议吗?

【问题讨论】:

  • 建议什么?你想要什么?你为什么要担心?当然,不同平台上的不同编译器在实现细节方面会做不同的事情……
  • 除非您插入未命名的、大小为零的位域,否则您不能对位域的布局做出任何假设。
  • 建议:如果内存布局或大小很重要,请不要使用位域,因为几乎没有任何保证。
  • 您可以在 Windows 上通过将它们都设为 uint16_t 来将它们打包为 2 个字节。

标签: c struct bit-fields


【解决方案1】:

不确定我是否理解得很好,但我看到虽然第一个编译器将结构压缩为 9+7 = 16 位,但另一个使用 16 位 uint16_t 和 8 位 uint8_t。你能建议吗?

关于位域,首先要记住的是来自 K&R, 2nd 的这句话:

(6.9 位字段)“几乎所有关于字段的内容都依赖于实现。”

它包括填充、对齐和位字节序。

【讨论】:

    【解决方案2】:

    可能会出现两个问题:

    位域在 ANSI C 规范中是非常不标准化的部分。编译器选择如何在位域容器中分配位。您应该避免在结构中使用它们,而是可以使用#define 或枚举。

    第二个可能的问题是编译器将通过添加填充将结构放置在内存中以确保下一个对象与该对象的大小对齐。根据其大小放置结构的元素是一个好习惯:

    typedef struct{
            uint8_t x : 7;
            uint16_t y : 9;
        } z;
    

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 2019-11-23
      • 2017-03-26
      • 2021-12-10
      • 2013-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-01
      相关资源
      最近更新 更多