为什么空数组的大小为 0 而空 class 的大小不为 0?
Why size of an empty array is 0 but size of an empty class is not 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;
}
请告诉我编译器行为背后是否有任何原因
编辑:假设g++
sizeof
returns 对象的字节大小 http://en.cppreference.com/w/cpp/language/sizeof
空数组的大小为0,因为里面没有字节。 struct 的大小一般不为零。如果编译器发现该结构为空,则会报告零。
在您的例子中,编译器可以判断出结构中的字节数为零。因此,sizeof(bar)
和 sizeof(baz)
为零
另见此处 http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#The-sizeof-Operator
这是一个仅限 C++ 的问题。在 C 中,编译器禁止空 struct
。
在 C++ 中,sizeof(foo) == 1
的最终原因是为了强制执行 C++ 标准的 "no object shall have the same address in memory as any other variable" 规则。您可以阅读详情here.
编辑:关于 user2864740
关于 baz
的评论似乎也应该是非零是正确的。编译器允许空数组,这使得精细化规则似乎没有像 foo
那样始终如一地应用于 baz
。事实上,这确实弄乱了指针算法。看这个例子:
// 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
确实很危险;这可能会导致无限循环。建议你不要再这么调皮了,就算你找到了逃脱的方法:)
例如:
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;
}
请告诉我编译器行为背后是否有任何原因
编辑:假设g++
sizeof
returns 对象的字节大小 http://en.cppreference.com/w/cpp/language/sizeof
空数组的大小为0,因为里面没有字节。 struct 的大小一般不为零。如果编译器发现该结构为空,则会报告零。
在您的例子中,编译器可以判断出结构中的字节数为零。因此,sizeof(bar)
和 sizeof(baz)
为零
另见此处 http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#The-sizeof-Operator
这是一个仅限 C++ 的问题。在 C 中,编译器禁止空 struct
。
在 C++ 中,sizeof(foo) == 1
的最终原因是为了强制执行 C++ 标准的 "no object shall have the same address in memory as any other variable" 规则。您可以阅读详情here.
编辑:关于 user2864740
关于 baz
的评论似乎也应该是非零是正确的。编译器允许空数组,这使得精细化规则似乎没有像 foo
那样始终如一地应用于 baz
。事实上,这确实弄乱了指针算法。看这个例子:
// 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
确实很危险;这可能会导致无限循环。建议你不要再这么调皮了,就算你找到了逃脱的方法:)