1

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?

LihO
  • 41,190
  • 11
  • 99
  • 167
CuriousGeorge
  • 7,120
  • 6
  • 42
  • 74
  • The linkage of class statics and non-static instances is both intentional and distinct. `Object::number` will exist even when **no** instances of `Object` exist, much less outlive any specific instance of `Object`. There is only one (unless it is a template, but technically thats not the same *class*, as it would be a generated deduction). – WhozCraig Mar 01 '13 at 17:38
  • 3
    Btw, the thing you're asking about is called "lifetime", not "scope". Scope is the part of a source file in which a name is visible. Lifetime is the period during runtime when an object exists. – Steve Jessop Mar 01 '13 at 17:41
  • @WhozCraig: On the other hand, I believe it's possible to construct and use an instance of `Object` before `Object::number` has been initialized... – Mooing Duck Mar 01 '13 at 17:41
  • 1
    @MooingDuck - I think that answers OP's precise question. – Robᵩ Mar 01 '13 at 17:43
  • @MooingDuck I'd have to seriously wrap myself into object lifetimes and global initializations and their format defs in the standard before I could confirm or deny that is possible, but it would not surprise me in the slightest if it was. Global init is always a flaky thing to me so I try to avoid it. – WhozCraig Mar 01 '13 at 17:43

5 Answers5

5

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]

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
4

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).

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
3

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".

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
2

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?"

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • 1
    I thought so too, but Mike Seymour observes there's a special case for objects that have `constexpr` constructors and primitives: § 3.6.2/2 – Mooing Duck Mar 01 '13 at 17:58
  • 1
    Right, so specifically OP does have the guarantee for the `Object` described in the question. But generally, he does not have such a guarantee for all other kinds of objects. – Robᵩ Mar 01 '13 at 18:18
1

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.

LihO
  • 41,190
  • 11
  • 99
  • 167