9
#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)

Community
  • 1
  • 1
simon_xia
  • 2,394
  • 1
  • 20
  • 32
  • 5
    Zero-sized arrays are non-standard (in fact the standard explicitly forbids them), so your question regarding the standard is moot. As for the size, if your compiler considers `sizeof(Empty) == 0` then you are dividing by zero, which is undefined behavior. – user657267 Sep 12 '14 at 08:54
  • 1
    FWIW; msvc outputs `error C2233: 'set' : arrays of objects containing zero-size arrays are illegal` – Niall Sep 12 '14 at 08:55
  • 1
    You're using zero-sized arrays (extension) and diving by zero – Marco A. Sep 12 '14 at 08:56
  • clang and gcc `-Wpedantic` warns about the zero sized arrays... – Niall Sep 12 '14 at 08:58
  • why would any compiler show sizeof(Empty) == 0? – zoska Sep 12 '14 at 09:04
  • `char omg[0]` does not have a size of zero. `omg` is the name of a pointer to a block of data of size zero. As such, `omg` is the size of a char pointer, and thus the class is at least that size. – iWiggins Sep 12 '14 at 21:22
  • 1
    @LID919 An array is not a pointer, it is only implicitly converted to one under certain circumstances. By your logic `sizeof(char[1]) == sizeof(char*)` which is nonsense, the standard makes it clear that the `sizeof` an array is the number of bytes in the array. – user657267 Sep 13 '14 at 00:34

1 Answers1

1

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.

user657267
  • 20,568
  • 5
  • 58
  • 77