CuriousGeorge
CuriousGeorge

Reputation: 7400

Scope of the static class data member

If I have a class:

Object.h

class Object
{
public:
    static int number;
};

Object.cpp

int Object::number = 5;

Is the scope of Object::number guaranteed to outlast the scope of any instance of Object that is created? even if it's declared globally in another source file?

Upvotes: 1

Views: 199

Answers (5)

Mike Seymour
Mike Seymour

Reputation: 254431

Yes, for two reasons:

  • It has static storage duration, so its storage lasts for the lifetime of the program
  • It has a type with no constructor, initialised with a constant expression.

Together, this means that it is initialised during the static initialisation phase, before any user-defined code (including constructors of static objects) is run. Therefore, it is guaranteed to exist, and be initialised, before any code can access it.

If it had a constructor, or a non-constant initialiser, then it would be initialised during dynamic initialisation along with all other such objects. In that case, it would be possible for another static object's constructor or initialiser to access the object before it is initialised. That problem is sometimes referred to as the "static initialisation order fiasco".

Upvotes: 3

Steve Jessop
Steve Jessop

Reputation: 279225

Sort of, but only because int is a special case. For example, suppose you write in Object.cpp:

Object o = {};
int Object::number = 5;

Then the object o has static storage duration, just like Object::number does. It is nominally created before number and will be destroyed afterwards, but since they're both POD this destruction actually has no effect.

If number and o had non-trivial destructors, though, then number would be destroyed before o. The fact that number is a static member of the class of o doesn't give it any special treatment as far as order of destruction is concerned.

If o is off in another source file, then order of construction is unspecified, and order of destruction is reverse order of construction (again, that's if they had non-trivial destructors -- int is a special case since it doesn't).

Upvotes: 4

Robᵩ
Robᵩ

Reputation: 168616

Consider this g++ program:

#include <iostream>
#define X() (std::cout << __PRETTY_FUNCTION__ << "\n")

struct M {
 M() { X(); }
 ~M() { X(); }
};  

struct C {
 C() { X(); }
 ~C() { X(); }
 static M m;
};
C c;
M C::m;
int main () { X(); }

In this program, c must be initialized before C::m, and must be destoryed after C::m. If you compile this program and consider its output, you'll see something like:

C::C()
M::M()
int main()
M::~M()
C::~C()

So, no, in general, "the [lifetime] of [a member]" is not "guaranteed to outlast the [lifetime] of any instance of Object that is created?"

Upvotes: 2

LihO
LihO

Reputation: 42083

It's guaranteed by the standard that objects with static storage duration exist during the entire duration of the program.

C++03, 3.7.1 Static storage duration §1:

All objects which neither have dynamic storage duration nor are local have static storage duration. The storage for these objects shall last for the duration of the program

and in your example §4 is also relevant:

The keyword static applied to a class data member in a class definition gives the data member static storage duration.

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129314

Yes, it has 'static storage duration', which means that it exists "all the time" [if it's got a non-standard constructor, the constructor is called before "main" starts - which should be enough for most intents and purposes]

Upvotes: 5

Related Questions