【发布时间】:2020-12-28 00:08:35
【问题描述】:
#include <stdio.h>
struct Obj {
char a;
uint32_t b;
uint8_t c;
uint64_t d[0];
};
struct Obj1 {
uint64_t d[0];
};
int main() {
uint64_t a[0];
printf("%d\n", sizeof(Obj)); // 16
printf("%d\n", sizeof(a)); // 16
printf("%d\n", sizeof(Obj1)); // 16
//cout << sizeof(Obj) << endl; // 16
//cout << sizeof(a) << endl; // 0
//cout << sizeof(Obj1) << endl; // 0
}
如上图,为什么struct内的uint64_t变量不会在uint8_t后面直接堆叠,更奇特的是空数组在结构外的大小为零。
这实际上是一道面试题。解释是这样的,虽然还是看不懂。
如果没有第四个字段,应该是4+4+4=12,加上第四个 字段为16,第四个字段不占空间,但会告诉 编译器对齐 8 个字节
这种用法经常在内核中使用,例如下面的可以 下标直接访问
Obj o1; uint64_t array[1024]; // In memory, array immediately follows
o1 o1.d[123]; // can access the elements of array
正如 cmets 所指出的,这可能仅适用于 C 而不是 C++。所以我把代码改成了C版本。
【问题讨论】:
-
Struct padding 可能是因为对齐?
-
这是未定义的行为。
-
绝对是UB。我不知道为什么在面试中被问到会改变任何事情。在采访中似乎是一个合理的答案。如果面试官说某些特定的输出是有保证的,那他们就错了。
-
@BAKEZQ 面试官确实错了。数组大小必须大于 0:timsong-cpp.github.io/cppwp/dcl.array#1.sentence-3
-
OP:你试过用
-pedantic编译这个吗? “警告:ISO C++ 禁止零大小数组”.
标签: arrays c structure padding memory-alignment