Why is the size of an empty class in C++ not zero? [duplicate]
Asked Answered
V

5

97

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

Why does the following output 1?

#include <iostream>

class Test
{
};

int main()
{
    std::cout << sizeof(Test);
    return 0;
}
Via answered 2/3, 2010 at 9:34 Comment(3)
There is a dummy placeholder member whose size happens to be one byte. Since for an array of Test[10], each object should have a unique address.Letourneau
An interesting optimization though is the Empty Base Optimization, meaning that if you inherit from an empty base class (no attribute, no virtual methods), then your class size won't grow. There are a number of (other) conditions, but it explains why privately inheriting from predicates in some situations.Bonsai
similar question 1 and similar question 2.Destructible
J
136

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.

Jumbuck answered 2/3, 2010 at 9:36 Comment(5)
Hm... but shouldn't the linker be able to take care of that regardless of what sizeof() returns? Isn't this more like a side-effect? I understand what you are saying, but isn't it perfectly doable to return 0 for sizeof(Test). But if the standard says so, it says so. Actually a good thing for once to be explicit instead of intentionally vague about a subject.Insulation
@Amigable, so what would Test a[10]; have as size? And sizeof a / sizeof *a would divide by 0. And for(Test *i = a; i != a + 10; i++) f(i); would also fail to work. I believe it would cause a lot of problems, as you need a lot of special cases in compilers and in user code.Benzoate
@Johannes, so true. I did not think about that.Insulation
@JohannesSchaub-litb: I disagree with your comment. sizeof a / sizeof *a would be 0/0 which would be consistent and "proper" behavior for zero size types (this is because Test a[10] and Test a[100] can not be distinguished, which is logical since they are both degenerate}). Also the for loop would NOT fail. This is because a + 10 = a. I dont see any logical inconsistency with zero size types, IMO not allowing them introduces inconsistencies. The only advantage this has is probably just the requirement that all objects have distinct addresses.Archaism
@AndreasH.: I mostly agree with you, and I think sizeof(Empty) should have been zero. But it is a bit more complicated because for(Test *i = a; i != a + 10; ++i) f(*i); would do a different thing from for(int i = 0; i < 10; ++i) f(a[i]). I've analyzed it in detail, including a proposed solution, at Legalization of empty objects.Unclean
A
38

To ensure that the addresses of two different objects will be different. For the same reason, "new" always returns pointers to distinct objects.

See Stroustrup for complete answer.

Airy answered 2/3, 2010 at 9:37 Comment(0)
D
31

The C++ standard guarantees that the size of any class is at least one. The C++ standard states that no object shall have the same memory address as another object. There are several good reasons for this.

  1. To guarantee that new will always return a pointer to a distinct memory address.

  2. To avoid some divisions by zero. For instance, pointer arithmetics (many of which done automatically by the compiler) involve dividing by sizeof(T).

Note however that it doesn't mean that an empty base-class will add 1 to the size of a derived class:

struct Empty { };

struct Optimized : public Empty {
    char c;
};

// sizeof(Optimized) == 1 with g++ 4.0.1

Bjarne Stroustrup talks about this too.

Draw answered 2/3, 2010 at 9:51 Comment(4)
What pointer arithmetic involves dividing by sizeof(T)? I can't think of a single example. Plase add at least one example.Fulllength
@MSalters: iterating over arrays of elements of type T.Draw
@MSalters: subtraction of two pointers returns the number of elements, not the number of bytes, in between.Pili
@Ben Voigt: good point, you're right. Iterating over an array just means adding sizeof(T) bytes to a pointer, but a poitner difference internally will be calculated first as a byte difference.Fulllength
A
13

Class without any data members and member function such type of class is known as empty class. Size of object of empty class is always 1 byte.

When we create object of any class at that time object always gets 3 characteristics i.e.

  1. State
  2. Behaviour
  3. Identity

When we create object of empty class at that time State of that object is nothing. Behaviour of that object is also nothing, but compiler assigns a unique address to that object. Memory in Computer is always organized in the form of bytes and minimum memory available at object address location is 1 byte. That's why size of object of empty class is 1 byte.

Around answered 17/10, 2011 at 7:55 Comment(1)
if any one wanted to knw abt 3 charecteristics of an object i.e. 1)State 2)Behaviour 3)Identity then ask meAround
E
4

What Maurits and Péter said.

It is interesting to note in this context that compilers can do empty base class optimization (EBCO):

#include <iostream>
struct Foo {};
struct Bar : Foo {};
int main () {
    std::cout << sizeof(Foo) << ',' << sizeof(Bar) << std::endl;        
}

This will probably print "1,1" if you compile and run it. See also Vandevoorde/Josuttis 16.2 on EBCO.

Emersen answered 2/3, 2010 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.