18

I'm wondering how static member variables are typically implemented in languages like C++ and if their use affects the size of instantiated objects.

I know that a static members are shared by all instances of that class, but how is it shared? If it affects object size, would having 10 static variables add more size than 1?

I'm asking because I can think of two ways it might be implemented:

  • adding a pointer to static data to each object similar to the way some implementations add a pointer to the virtual function table
  • the static data is just referenced directly like a global variable with the offset being resolved by the linker / loader
River
  • 8,585
  • 14
  • 54
  • 67
Robert S. Barnes
  • 39,711
  • 30
  • 131
  • 179
  • 1
    This is the kind of question you could easily test yourself. Just create the appropriate classes and do sizeof(T) it will tell you how big they are. – Martin York Jan 09 '11 at 20:33
  • @Martin York: AFAIK, there is no sizeof operator in Java. – Robert S. Barnes Jan 09 '11 at 20:52
  • 1
    [in-java-what-is-the-best-way-to-determine-the-size-of-an-object](http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object) – Martin York Jan 09 '11 at 22:08

2 Answers2

31

In C++, static members don't belong to the instances of class. they don't increase size of instances and class even by 1 bit!

struct A
{
    int i;
    static int j;
};
struct B
{
    int i;
};
std::cout << (sizeof(A) == sizeof(B)) << std::endl;

Output:

1

That is, size of A and B is exactly same. static members are more like global objects accessed through A::j.

See demonstration at ideone : http://www.ideone.com/YeYxe


$9.4.2/1 from the C++ Standard (2003),

A static data member is not part of the subobjects of a class. There is only one copy of a static data member shared by all the objects of the class.

$9.4.2/3 and 7 from the Standard,

once the static data member has been defined, it exists even if no objects of its class have been created.

Static data members are initialized and destroyed exactly like non-local objects (3.6.2, 3.6.3).

As I said, static members are more like global objects!

River
  • 8,585
  • 14
  • 54
  • 67
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • @Nawaz: Interesting. So if we want to serialise A we can not just assume that the necessary memory is the result of sizeof(A). Right? How can we know the real size then? – Nerian Jan 09 '11 at 18:51
  • 4
    static variables are not part of the object itself and should not get serialized like it is. – Vinay Pai Jan 09 '11 at 18:55
  • 1
    @Nerian : serialization also depends on what members you want to include in the serialized object, and what not. since static members don't belong to the *instances* of the classes, then most likely you don't want to serialize it either; they are more like global objects accessed using `A::j`. Anyway, don't trust me opinion. I don't know much about serialization. Ask someone who knows. And start another topic. :-) – Nawaz Jan 09 '11 at 18:58
  • @Nerian: Vinay seems to be agree with me. :-) – Nawaz Jan 09 '11 at 18:58
  • Is this true in Java and other languages as well? – Robert S. Barnes Jan 09 '11 at 19:02
  • @Robert: Yes. But there may be subtle differences which I may be unaware of. But in general, static members don't belong to the *instances* of class. – Nawaz Jan 09 '11 at 19:05
  • 1
    +1: for the link to ideone.com, first time I've seen it. Very Cool! – Robert S. Barnes Jan 09 '11 at 19:06
  • @Nawaz: I don't suppose you might be able to refer to any paragraph in a standard? Or is this purely an implementation detail that happens to end up implemented the same way 99% of the time? – Robert S. Barnes Jan 09 '11 at 19:07
  • 3
    @Robert This can be inferred from the definition of POD types; the Standard carefully states that adding `static` members cannot turn a POD type into a non-POD type. And the memory layout of POD type is strictly defined. – anatolyg Jan 09 '11 at 19:10
  • @anatolyg: where is the layout of POD types strictly defined? Padding is left to the implementation. I don't think there's any good reason for a compiler to do this, but suppose an implementation chose to add an extra byte of padding to the end of any class with static members. Does the standard forbid that? – Steve Jessop Jan 09 '11 at 19:22
  • @Robert: I've quoted from the Standard. Please see my answer! – Nawaz Jan 09 '11 at 19:25
  • @Steve Indeed, my assertion on POD layout was incorrect; the definition of layout-compatible types (9.2-14) doesn't mention "non-static" (so the compiler could really add padding/pointer-to-static-variables to the end of the object) – anatolyg Jan 09 '11 at 20:09
  • @anatolyg: Hmm, I think my hypothetical implementation can only do what I said for non-POD types. 9.2-14 does say "nonstatic" data members in the final C++03. – Steve Jessop Jan 09 '11 at 20:53
6

Static members are resolved by the compiler at compile-time. In many ways static variables are no different than global variables under the hood. The differences only lie in how you refer to them in your code, the scope where they are visible, and how and when they get initialized.

Vinay Pai
  • 7,432
  • 1
  • 17
  • 28
  • Would you add a link for reference material which further explains your answer, please? – David Weiser Jan 09 '11 at 18:56
  • 2
    @David: I'm not Vinay, of course, but I'm not sure what sort of reference material would address this. I think Vinay's answer is best supported by what's *not* in the language specifications for C++ and Java, respectively: Nothing in the definitions suggests that static variables *would* impose a runtime overhead on class instances; therefore, they don't. – Dan Breslau Jan 09 '11 at 19:10