关于C#:结构体是否可以小于其组件的总和?

Can a struct be smaller than the sum of its components?

我知道编译器可以在结构中添加一些填充字节。但是,当编译器发现我们从未从结构内部的变量中读取数据时,结构的大小是否可能小于成员的总大小?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Foo_T
{
  int a;
  intmax_t b;
};


void bar(void)
{
  struct Foo_T foo;
  foo.a=rand();
  someFunction(foo.a);
  //i never access foo.b, only foo.a
  if(sizeof(foo)< sizeof(int)+sizeof(intmax_t))
    {
      //is it possible that we can end here?
    }
}


不,这是C标准禁止的。在C11中,第6.7.2.1节包含以下声明:

15 Within a structure object, the non-bit-field members and
the units in which bit-fields reside have addresses that increase
in the order in which they are declared. [... ] There may be unnamed padding within
a structure object, but not at its beginning.

删除struct的成员将违反成员拥有地址的要求,地址的声明顺序将增加。


不,不可能。当你服用sizeof(foo)时,你期望至少得到sizeof(int) + sizeof(intmax_t)。如果编译器给你一个较小的大小,它会错误地影响程序的行为,这是不允许的。

假设您将最后一个成员放在那里作为占位符"dummy",以确保不使用保留的硬件寄存器,或者确保正确对齐。如果编译器删除这样一个成员,它就会破坏程序。


绝对不是。

任何编译器都应该如何预测您明天要写的内容?事实上,所有当前的源代码都不使用该元素,这决不能保证永远不会有源代码试图访问结构的该部分。


如果一个结构是在一个自动或静态变量中声明的,并且该结构或其任何部分的地址都没有被获取和使用,那么编译器可能无法100%理解,如果使用该结构的所有代码都被相应地调整,那么编译器就可以更改该结构的布局。重要的是,除了使用语言之外的机制(例如,使用调试器查看内存布局,或访问没有定义用途的内存区域),代码无法确定编译器是否执行了这样的操作。