Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Something about a completely empty class

#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;
}

Its output is:

0 0 0

0xbff36ad0 0xbff36ac8

numbers of elements is: 4

The results are so surprising.

As shown above, Empty is a class, the size of it and its objects are all 0, why?

Maybe I guess, because a empty class's size is 1, and when the class is not empty, its size is decided by is members, but here its member is special, it is a Arrays of Length Zero, and this array's size is 0, so the size of class and objects are all 0.

It's just my guess. As the program running, we can see that two objects both have address, and the address is different.

Here is my question: if object of 0 size can be implemented, Why the C++ standard states that empty objects have sizeof() = 1, it is for "To ensure that the addresses of two different objects will be different"Why is the size of an empty class not zero? , but now, we do have different address as the output,how does this happen?

Further more, no matter what the size of the array set is, the last line output is always 4, why?

Thanks :)

PS: I run this program on MacOS, and the compiler is Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)

like image 450
simon_xia Avatar asked Sep 12 '14 08:09

simon_xia


Video Answer


1 Answers

I'll take a stab since no one more experienced has:

As shown above, Empty is a class, the size of it and its objects are all 0, why?

Zero-sized arrays are prohibited by the standard, therefore as far as the standard is concerned sizeof(Empty) is a meaningless expression, you are already in the realm of undefined behaviour.

Here is my question: if object of 0 size can be implemented, [...] Why is the size of an empty class not zero? , but now, we do have different address as the output,how does this happen?

As above, an object of size 0 cannot exist in a valid standard c++ program (with the exception of base class subobjects).

Your compiler allows this as an extension to the standard, and as long as you use this extension within the scope it was intended for (i.e. as a pre-flexible array member hack) you shouldn't have any problems, although your code is not portable. Your example above however is not how zero-sized arrays are meant to be used (not to mention there are better constructs in c++ for handling these situations anyway).

Your compiler is intelligent enough to provide separate addresses for em1 and em2, but you should find that all elements of set have in fact the same address.

Further more, no matter what the size of the array set is, the last line output is always 4, why?

Since your compiler considers sizeof(Empty) and arrays of Empty to be zero, you are dividing by zero, which is undefined behavior. You might find your program crashes if you disable optimizations, with GCC for instance your program crashes with -O0 but not with -O1.

like image 82
user657267 Avatar answered Nov 15 '22 18:11

user657267