tags:

views:

437

answers:

4

Why does the following output 1?

#include <iostream>

class Test
{
};

int main()
{
    std::cout << sizeof(Test);
    return 0;
}
+33  A: 

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.

Péter Török
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.
Amigable Clark Kant
@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.
Johannes Schaub - litb
@Johannes, so true. I did not think about that.
Amigable Clark Kant
+17  A: 

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.

Maurits Rijk
+8  A: 

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.

wilhelmtell
What pointer arithmetic involves _dividing_ by `sizeof(T)`? I can't think of a single example. Plase add at least one example.
MSalters
@MSalters: iterating over arrays of elements of type T.
wilhelmtell
@MSalters: subtraction of two pointers returns the number of elements, not the number of bytes, in between.
Ben Voigt
@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.
MSalters
+2  A: 

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.

phresnel