为什么空数组的大小为0但空类的大小不是0?
int main() {
struct {} foo;
int bar[0];
struct {
int dummy[0];
} baz;
cout << sizeof(foo) << endl; //display '1'
cout << sizeof(bar) << endl; //display '0'
cout << sizeof(baz) << endl; //display '0'
return 0;
}
请告诉我有什么原因立场背后的编译器行为
这是一个C++的唯一问题。在C中,编译器禁止使用空的struct
。
在C++中,sizeof(foo) == 1
的原因最终使得C++标准的“无对象应该在内存中具有与任何其他变量相同的地址”的规则可以被强制执行。您可以阅读详细信息here。
编辑:关于user2864740
约baz
出现,这也应该是非零的评论是正确的。编译器允许使用空数组,这使得看起来finessing规则没有被一致地应用到baz
,就像它是到foo
一样。事实上,这确实弄乱了指针算术。看到这个例子:
// C++14 code
#include <iostream>
using namespace std;
int main() {
struct baz {
int dummy[1];
};
cout << sizeof(baz) << endl;
baz* arr;
arr = new baz[5];
cout << &arr[0] << endl;
cout << &arr[1] << endl;
return 0;
}
// everything looks good
4
0x892c008
0x892c00c
但是,如果我们采取相同的代码和改变内部baz
数组是int dummy[0];
,那么我们得到如下的输出:
0
0x8fe3008
0x8fe3008
危险确实;这可能会导致无限循环。建议你不要这样顽皮,即使你已经找到了逃避它的方法:)
我很困惑(阅读文章后),因为'巴兹'有0大小。看起来规则也会规定它有1 /非零大小。 (除非与原代码是一个坏例子。) – user2864740
@ user2864740这是因为你的代码不符合C++标准。你不能有这样的长度为零的数组。 *编辑*:看起来它是一个gcc扩展名,所以你可以不使用它或在gcc手册中阅读它应该如何工作。 – juanchopanza
我不会说OP会欺骗编译器。如果行为没有在编译器文档中指定,我会感到震惊。 – chris
编辑:假设g++
sizeof
返回对象的字节大小http://en.cppreference.com/w/cpp/language/sizeof
空的大小数组为0,因为它中没有字节。结构的大小通常不是零。如果编译器发现结构是空的,那么它将报告一个零。
就你而言,编译器可以知道结构中的字节数为零。因此,sizeof(bar)
和sizeof(baz)
为零
看到这里也http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#The-sizeof-Operator
C++不允许'sizeof(a_struct)'为零。它也不允许自动或静态存储阵列的大小为0. – juanchopanza
这是一个gcc扩展https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Empty-Structures.html#Empty-结构“结构的大小为零”。回答编辑。 – bendervader
这很有趣。但请注意,这不是C++。 – juanchopanza
C++甚至不允许零大小的数组。 C只有在大小不是一个常量表达式时才会执行。您应该在第二个和第三个案例中阅读编译器的文档以了解它的行为,因为它们是由编译器扩展而不是标准所涵盖的。 – chris
相关:http://*.com/questions/6180012/array-with-size-0 – juanchopanza
**哪种语言?** C和C++是巨大的不同。特别是在这方面。你不能指望一个明智的答案“C/C++”。您可以询问C ** xor ** C++。 –