结构可以小于其组件的总和吗?
Can a struct be smaller than the sum of its components?
我知道编译器可能会在结构中添加一些填充字节。但是,当编译器发现我们从未从结构中的变量读取时,该结构的大小是否可能小于成员的总大小?
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?
}
}
不,这是不可能的。当您服用 sizeof(foo)
时,您预计至少会得到 sizeof(int) + sizeof(intmax_t)
。如果编译器给你一个较小的大小,它会错误地影响程序的行为,这是不允许的。
假设您将最后一个成员放在那里作为占位符 "dummy",以保证不使用保留的硬件寄存器,或确保正确对齐。如果编译器删除这样的成员,它就会破坏程序。
不,C standard 禁止这样做。在 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
的成员将违反成员地址按其声明顺序递增的要求。
如果结构是在自动变量或静态变量中声明的,并且结构或其任何部分都没有以编译器不能 100% 理解的任何方式获取和使用其地址,则编译器可以更改如果相应地调整了使用该结构的所有代码,则该结构的布局。重要的是,除非使用语言之外的机制(例如,使用调试器查看内存布局,或访问未定义用途的内存区域),否则代码无法确定编译器是否执行此类操作。
绝对不是。
任何 编译器应该如何预测您打算明天写什么?所有 current 源代码 not 使用该元素的事实绝不保证永远不会有源代码试图访问该元素结构的一部分。
我知道编译器可能会在结构中添加一些填充字节。但是,当编译器发现我们从未从结构中的变量读取时,该结构的大小是否可能小于成员的总大小?
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?
}
}
不,这是不可能的。当您服用 sizeof(foo)
时,您预计至少会得到 sizeof(int) + sizeof(intmax_t)
。如果编译器给你一个较小的大小,它会错误地影响程序的行为,这是不允许的。
假设您将最后一个成员放在那里作为占位符 "dummy",以保证不使用保留的硬件寄存器,或确保正确对齐。如果编译器删除这样的成员,它就会破坏程序。
不,C standard 禁止这样做。在 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
的成员将违反成员地址按其声明顺序递增的要求。
如果结构是在自动变量或静态变量中声明的,并且结构或其任何部分都没有以编译器不能 100% 理解的任何方式获取和使用其地址,则编译器可以更改如果相应地调整了使用该结构的所有代码,则该结构的布局。重要的是,除非使用语言之外的机制(例如,使用调试器查看内存布局,或访问未定义用途的内存区域),否则代码无法确定编译器是否执行此类操作。
绝对不是。
任何 编译器应该如何预测您打算明天写什么?所有 current 源代码 not 使用该元素的事实绝不保证永远不会有源代码试图访问该元素结构的一部分。