#include <iostream>
using namespace std;
class Empty{
char omg[0];
};
int main()
{
Empty em1, em2;
Empty set[100];
cout << sizeof(Empty) << " " << sizeof(em1) << " " << sizeof(em2) << endl;
cout << (long*)&em1 << " " << (long*)&em2 << endl;
cout << "total numbers of element is: " << sizeof(set)/sizeof(*set) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它的输出是:
0 0 0
0xbff36ad0 0xbff36ac8
元素数量是:4
结果令人惊讶.
如上图所示,Empty是一个类,它的大小和它的对象都是0,为什么呢?
也许我猜,因为空类的大小是1,当类不是空时,它的大小由成员决定,但是这里的成员是特殊的,它是一个长度为0的数组,这个数组的大小是0,所以类和对象的大小都是0.
这只是我的猜测.当程序运行时,我们可以看到两个对象都有地址,地址不同.
这是我的问题:如果可以实现0大小的对象,为什么C++标准声明空对象的sizeof()= 1,它是为了"确保两个不同对象的地址不同" 为什么是大小一个空类不是零?,但现在,我们确实有不同的地址作为输出,这是怎么发生的?
而且,无论数组的大小是多少,最后一行输出总是4,为什么?
谢谢 :)
PS:我在MacOS上运行这个程序,编译器是Apple LLVM版本5.1(clang-503.0.40)(基于LLVM 3.4svn)
我会尝试一下,因为没有人更有经验:
\n\n\n\n\n如上所示,Empty是一个类,它和它的对象的大小都是0,为什么呢?
\n
标准禁止零大小的数组,因此就标准而言sizeof(Empty)是一个无意义的表达式,您已经处于未定义行为的领域。
\n\n\n这是我的问题:如果可以实现 0 大小的对象,[...]为什么空类的大小不为零?,但是现在,我们确实有不同的地址作为输出\xef\xbc\x8chow,这种情况会发生吗?
\n
如上所述,大小为 0 的对象不能存在于有效的标准 C++ 程序中(基类子对象除外)。
\n\n您的编译器允许将此作为标准的扩展,只要您在其预期范围内使用此扩展(即作为预灵活数组成员黑客),您就不应该遇到任何问题,尽管您的代码不是便携的。然而,上面的示例并不是零大小数组的使用方式(更不用说 C++ 中有更好的构造来处理这些情况)。
\n\n您的编译器足够智能,可以为em1和提供单独的地址em2,但您应该发现 的所有元素set实际上具有相同的地址。
\n\n\n更进一步,无论数组集合的大小是多少,最后一行输出总是4,为什么呢?
\n
由于编译器认为sizeof(Empty)和 数组Empty为零,因此您除以零,这是未定义的行为。如果禁用优化,您可能会发现程序崩溃,例如,使用 GCC 时程序会崩溃-O0,但使用-O1.
| 归档时间: |
|
| 查看次数: |
495 次 |
| 最近记录: |