This is pretty much a repetition of what other answers have already said, but a few more references to the ISO C ++ standard and some thoughts about the odd behavior of g ++.
The ISO C ++ 11 standard in section 8.3.4 [dcl.array], paragraph 1, states:
If there is a constant expression (5.19), it must be an integral constant expression and its value must be greater than zero.
Your class definition:
class Test { int arr[0]; };
violates this rule. Section 1.4 [intro.compliance] is applicable here:
If the program contains a violation of any diagnosed rule [...], the corresponding implementation must issue at least one diagnostic message.
As I understand it, if the compiler issues this diagnostic and then accepts the program, the behavior of the program is undefined. So the whole standard has to say about your program.
Now this is a question about the compiler, not about the language.
I am using g ++ version 4.7.2, which allows arrays of zero size as an extension, but displays the required diagnostics (warning) if you call it, for example, -std=c++11 -pedantic :
warning: ISO C++ forbids zero-size array 'arr' [-pedantic]
(Apparently you are also using g ++.)
The experiment shows that g ++ handling zero-sized arrays is a bit odd. Here is an example based on one in your program:
#include <iostream> class Empty { /* This is valid C++ */ }; class Almost_Empty { int arr[0]; }; int main() { Almost_Empty arr[2]; Almost_Empty x, y; std::cout << "sizeof (Empty) = " << sizeof (Empty) << "\n"; std::cout << "sizeof (Almost_Empty) = " << sizeof (Almost_Empty) << "\n"; std::cout << "sizeof arr[0] = " << sizeof arr[0] << '\n'; std::cout << "sizeof arr = " << sizeof arr << '\n'; if (&x == &y) { std::cout << "&x == &y\n"; } else { std::cout << "&x != &y\n"; } if (&arr[0] == &arr[1]) { std::cout << "&arr[0] == &arr[1]\n"; } else { std::cout << "&arr[0] != &arr[1]\n"; } }
I received the required warning on int arr[0]; and then the following output:
sizeof (Empty) = 1 sizeof (Almost_Empty) = 0 sizeof arr[0] = 0 sizeof arr = 0 &x != &y &arr[0] == &arr[1]
C ++ requires that a class, even one without members, be at least 1 byte in size. g ++ follows this requirement for an Empty class that has no members. But adding a zero-size array to the class actually leads to the class having a size of 0.
If you declare two objects of type Almost_Empty , they have different addresses, which is reasonable; the compiler can select various objects as it sees fit.
But for elements in the array, the compiler has less flexibility: an array of N elements must have a size N times the number of elements.
In this case, since the Almost_Empty class has a size of 0, it follows that the array of Almost_Empty elements has a size of 0 * and that all elements of such an array have the same address.
This does not mean that g ++ does not comply with the C ++ standard. He did his job by printing out a diagnosis (even though it was not a deadly warning); after that, with regard to the standard, he can do whatever he likes.
But I would probably argue that this is a bug in g ++. From a common sense point of view, adding an empty array to a class should not reduce the class.
But there is a justification for this. As DyP points out in a comment, the gcc manual (which covers g ++) mentions this function as a C extension, which is also available for C ++ . They are primarily intended to be used as the last element of the structure, which is indeed the title for a variable-length object. This is called a struct hack . It is replaced on C99 with flexible array elements, and in C ++ with container classes.
My advice: avoid all this confusion without specifying arrays of zero length. If you really need sequences of elements that may be empty, use one of the standard C ++ container classes, for example std::vector or std::array .