Why Is the Size of an Empty Class in C++ Not Zero

Why is the size of an empty class in C++ not zero?

The standard does not allow objects (and classes thereof) of size 0, since that would make it possible for two distinct objects to have the same memory address. That's why even empty classes must have a size of (at least) 1.

Why is the size of an empty class in C++ not zero?

The standard does not allow objects (and classes thereof) of size 0, since that would make it possible for two distinct objects to have the same memory address. That's why even empty classes must have a size of (at least) 1.

Why is the size of an empty class not zero in C#?

  • "0" takes up some space itself to store - if you store it as a 4 byte number it takes up 4 bytes!
  • Of course this information about the class has to take up memory otherwise where would you read it from?

A C# "class" as defined on MSDN

A class is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared as static, client code can use it by creating objects or instances which are assigned to a variable. The variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as static, then only one copy exists in memory and client code can only access it through the class itself, not an instance variable.

C++: What is the size of an object of an empty class?

Quoting Bjarne Stroustrup's C++ Style and Technique FAQ, the reason the size is non-zero is "To ensure that the addresses of two different objects will be different." And the size can be 1 because alignment doesn't matter here, as there is nothing to actually look at.

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

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 :)

Why the size of empty class that is derived from two empty classes is 2?

To me it seems that whether or not the empty base optimization can be applied here, depends on how one interprets [intro.object/8]:

Unless an object is a bit-field or a base class subobject of zero
size, the address of that object is the address of the first byte it
occupies. Two objects a and b with overlapping lifetimes that are not
bit-fields may have the same address if one is nested within the
other, or if at least one is a base class subobject of zero size and
they are of different types
; otherwise, they have distinct addresses.

Are B and C different types? They both are an A as well. Two distinct A objects actually. A compiler writer is allowed to stop right there an allocate storage for B and C separately, without checking that A is empty.

It's worth noting that with g++ the size is back to 1 if you have B and C inherit from separate bases:

Live Example

#include<iostream>

class A {};
class A1 {};
class B : public A {};
class C : public A1 {};
class D : public B, public C {};

int main() {
std::cout << "Size of D is: " << sizeof(D) << std::endl;
return 0;
}

Can sizeof a class or object ever be zero?

It's called "flexible array member" and it's a feature of C99 (I think). It's not valid C++ - you don't have warnings/errors, probably because the compiler supports it as an extension.

Compiling with -Wall -Wextra -pedantic -std=c++NN (98, 03, 11, 14, ..) should generate warning (the last two flags will disable any compiler extensions).


You can see some information in this related question: Is using flexible array members in C bad practice?

For example, here's what GCC says about this:

In ISO C99, you would use a flexible array member, which is slightly different in syntax and semantics:

...

Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.

(source: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html).

This explains the 0 size of char a[] and not the 0 for the class, but as I already mentioned - it's a C feature and not a valid C++.

what is the size of empty class in C++,java?

Short Answer for C++:

The C++ standard explicitly says that a class can not have zero size.

Long Answer for C++:

Because each object needs to have a unique address (also defined in the standard) you can't really have zero sized objects.

Imagine an array of zero sized objects. Because they have zero size they would all line up on the same address location. So it is easier to say that objects can not have zero size.

Note:

Even though an object has a non zero size, if it actually takes up zero room it does not need to increase the size of derived class:

Example:

#include <iostream>

class A {};
class B {};
class C: public A, B {};

int main()
{
std::cout << sizeof(A) << "\n";
std::cout << sizeof(B) << "\n";
std::cout << sizeof(C) << "\n"; // Result is not 3 as intuitively expected.
}

g++ ty.cpp
./a.out
1
1
1


Related Topics



Leave a reply



Submit