Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

c++ - Non local static viariable as members of a class

There are several questions out there about static variables, but I have not yet found an answer to my question. I just read Scott Meyers' explanation on the initialization of static variables and possible issues with it, like the static initialization order fiasco. What I would like to know is this: are static variables at class scope considered non-local?

Most sources I have seen say that static non local variables are defined either at global namespace or in a namespace while static local variables are defined in functions. But consider these two translations unit:

// MyClass.h:
class MyClass
{
public:
    static int z; // Is this non local?
};

// MyClass.cpp:
int MyClass::z = 4;

// MyOtherClass.h:
class MyOtherClass
{
public:
    static int w;
};

// MyOtherClass.cpp:
int MyOtherClass::w = MyClass::z; // Potential fiasco?

Is z non local? In other words, can we assume z is initialized when w is?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Both MyClass::z and MyOtherClass::w are non-local, static variables.

Your example potentially contains problems.

It's because MyOtherClass::w refers to MyClass::z, which potentially (from the viewpoint of compiling MyOtherClass) requires dynamic initialization [basic.start.static/3]:

An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that

  • the dynamic version of the initialization does not change the value of any other object of static or thread storage duration prior to its initialization, and

  • the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically.

[?Note: As a consequence, if the initialization of an object obj1 refers to an object obj2 of namespace scope potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was statically initialized) or will be the value of obj2 merely zero-initialized. For example,

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;     // unspecified:
                    // may be statically initialized to 0.0 or
                    // dynamically initialized to 0.0 if d1 is
                    // dynamically initialized, or 1.0 otherwise 
double d1 = fd();   // may be initialized statically or dynamically to 1.0

—?end note?]

So when the compiler compiles MyOtherClass.cpp, it doesn't know which way MyClass::z will be actually initialized, so it falls into the "not required to be initialized statically" category. And then it is unspecified, what value MyOtherClass::w will have. It could have

  • 0, when the compiler choose to statically initialize it

  • 4, if the compiler choose to dynamically initialize it

Thanks to StoryTeller for drawing attention to this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...