📜  为什么空结构在 C++ 中的大小为 1 个字节,而在 C 中为 0 个字节(1)

📅  最后修改于: 2023-12-03 15:21:37.394000             🧑  作者: Mango

空结构的大小差异

在 C 和 C++ 中,一个空结构体并不真的是没有成员,否则它将失去它的意义。而一个结构体的大小,在很多情况下,会涉及到字节对齐、编译器的实现方式等因素。因此,空结构体的大小并不是一个固定值。

然而,C 和 C++ 在此处的处理方式有所不同,也就是为什么在 C 中,空结构体的大小为 0,而在 C++ 中则为 1 个字节。

C 中的空结构体

在 C 中,对于一个结构体的大小,会按照所包含的实际成员变量的大小,对齐方式来确定。因为空结构体没有实际成员变量,所以它的大小为 0 字节。根据 C 语言标准,§6.2.6.1/6,这是合法的:

"The size of a struct with no fields is zero.

  没有成员的结构体的大小是零。

同时,因为每一个结构体的地址都是唯一的,所以,在 C 中空结构体不是一个 "空的类型"。

C++ 中的空结构体

C++ 中的空结构体和 C 有所不同,它并不是一个 ''真正的'' 空结构体,因为它至少包含一个字节的空间。这是因为 C++ 中,增强了类型的安全性,可以防止使用空结构体作为一个指针的位置(将会指向内存地址 0x0)。因此,为了保证空结构体也是一个安全类型,C++ 编译器在为其分配空间时,自动为其添加了一字节的大小。

我们可以参考 C++2003 标准,§9.2/16

"An object of class type must have its non-static data members allocated in a way that respects the principles of alignment imposed by the need to make that object properly aligned for its type.

  类类型的对象的非静态数据成员必须以一种尊重所需使该对象针对其类型正确对齐的原则分配。

用非常通俗易懂的语言解释一下,就是为了满足数据的对齐方式,编译器在分配内存时必须是以一个字节的倍数来分配的。如果整体大小不是字节的倍数的话,编译器就会自动填充一些空白字节,以便数据对齐。而在 C++ 中,由于空结构体没有成员变量,因此它无法被自动补齐,只好在中间插入一个字节,来保证它可以被正确对齐。

结论

在 C 和 C++ 中,对于一个空结构体的大小,它们有不同的处理方式,对于 C,它保持了 "没有成员的结构体大小是零" 的原则;而对于 C++,它为了保证类型的安全性,在空结构体中插入了一个字节来保证它的对齐方式。这也是我们在选择语言时需要注意的地方,不同的语言会有不同的实现方式。