3

Since in C++ sizeof of an empty class is 1 byte, is the following code valid?

class A
{
};

int main()
{
    A a;
    char* p = reinterpret_cast<char*>(&a);
    *p = 'a';
}

I know its pretty much useless, but just wanted to see whether I can do this. It compiles and runs fine on MSVC2010.

LihO
  • 41,190
  • 11
  • 99
  • 167
Asha
  • 11,002
  • 6
  • 44
  • 66
  • 2
    It's at least one byte. Could be more. Runs fine on gcc as well, so I'm inclined to agree you can do this, even though it's not safe and completely useless, like you said. – StoryTeller - Unslander Monica Feb 11 '13 at 11:19
  • The code is valid since it compiles. Whether or not it is correct or useful is another matter. – Pete Feb 11 '13 at 13:10
  • Just a side note: in C++, `return 0;` can be omitted in `main` – LihO Feb 11 '13 at 13:15
  • 1
    @Pete: Perhaps in PHP, but the C++ standard has "Undefined behavior, no diagnostic required" clauses. That means you can't infer valid, defined behavior from a lack of diagnostics. – MSalters Feb 11 '13 at 13:19
  • @MSalters depends what is meant by 'valid'. Perhaps I deserve a pedantic response for being pedantic in the first place – Pete Feb 11 '13 at 14:47

1 Answers1

1

C++03 standard 1.8 The C+ + object model:

Relevant parts of §1: An object is a region of storage... Some objects are polymorphic... For other objects, the interpretation of the values found therein is determined by the type of the expressions used to access them."

In your example, a is an object with automatic storage duration that is deallocated when the execution leaves the scope. Basically, memory where it resides is available to you and you can store whatever you want there:

int i;
char* myStr = reinterpret_cast<char*>(&i);
myStr[0] = 'H';
myStr[1] = 'i';
myStr[2] = '!';
myStr[3] = '\0';
std::cout << myStr;

(Full example is here)

What you should consider here is the lifetime of object that you "abuse" in this way, i.e. if you still keep the pointer to this memory even after the object has been deallocated, accessing this memory will lead to undefined behaviour.

Just note that just because the language allows you to do something, it doesn't mean you should do it. Use features of this language the way they were meant to be used. After all, you are not writing codes just so that "it works".


And to your question about the size of empty class, same part of the standard also says:

§4: If a complete object, a data member (9.2), or an array element is of class type, its type is considered the most derived class, to distinguish it from the class type of any base class subobject; an object of a most derived class type is called a most derived object.

§5: Unless it is a bit-field (9.6), a most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Base class sub-objects may have zero size. An object of POD type (3.9) shall occupy contiguous bytes of storage.

So it is guaranteed by standard that objects of an empty class such as yours will occupy at least 1 byte.

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
  • Yes, this was just for fun. I am not going to use it in production code. The question was specifically about the empty classes and whether I can "use" the 1 byte (the minimum guaranteed) that is allocated for such classes. – Asha Feb 11 '13 at 12:32