Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why size of an empty array is 0 but size of an empty class is not 0?

Tags:

c++

gcc

g++

For example:

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

Please tell me is there any reason stand behind that compiler behaviour

like image 519
DMaster Avatar asked Jun 21 '15 05:06

DMaster


People also ask

What is the size of an empty array?

The size of an empty array is 0, because there are no bytes in it. The size of struct, in general is not zero.

Can you make an array of size 0?

Although the size of a zero-length array is zero, an array member of this kind may increase the size of the enclosing type as a result of tail padding. The offset of a zero-length array member from the beginning of the enclosing structure is the same as the offset of an array with one or more elements of the same type.

Can you have an array of size 0 in Java?

Java allows creating an array of size zero. If the number of elements in a Java array is zero, the array is said to be empty. In this case you will not be able to store any element in the array; therefore the array will be empty.

What is the size of an empty class in Java?

Because they have zero size they would all line up on the same address location.


2 Answers

This is a C++ only issue. In C, an empty struct is prohibited by the compiler.

In C++, the reason for the sizeof(foo) == 1 is ultimately so that the C++ Standard's rule of "no object shall have the same address in memory as any other variable" can be enforced. You can read the details here.

EDIT: Regarding the comment by user2864740 about baz appearing that it should also be non-zero is correct. The compiler is allowing the empty array which makes it appear that the finessing rule is not being applied consistently to baz like it was to foo. This does, in fact, mess up the pointer arithmetic. See this example:

// 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

But if we take the same code and change the array inside baz to be int dummy[0];, then we get this output:

0
0x8fe3008
0x8fe3008

Dangerous indeed; this could lead to infinite loops. It is recommended you don't be naughty like this even if you've found a way to get away with it :)

like image 188
Special Sauce Avatar answered Nov 15 '22 05:11

Special Sauce


Edit: Assuming g++

sizeof returns the size of object in bytes http://en.cppreference.com/w/cpp/language/sizeof

The size of an empty array is 0, because there are no bytes in it. The size of struct, in general is not zero. If the compiler figures out that the struct is empty, then it will report a zero.

In your case, the compiler can tell that the number of bytes in the struct is zero. Hence, sizeof(bar) and sizeof(baz) is zero

See here also http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#The-sizeof-Operator

like image 36
bendervader Avatar answered Nov 15 '22 07:11

bendervader