Constructor sequence / execution order: dependent initialization of a static variable (class instance) in a function

For the following code segment:

class Bar { public: int x; int y; Bar(int _x, int _y) { /* some codes here */ ...} }; class Foo { public: int x; int y; int z; Foo(Bar b):x(bx), y(by) { z = someFunction(x, y); } }; void f(int x, int y) { Bar b(x, y); static Foo x(b); } int main() { f(2, 3); } 

In my opinion, the static variable inside the function should be initialized before main() . However, the static variable x type Foo depends on the local variable b type Bar .

Questions:

1) When is constructor x executed? those. Are x initialized with the first call to local variable b ? I don’t need any specific result of any special case of the compiler, but I want to know if it is well defined in C ++.

2) Is this a valid program?

3) Is this a good practice?

+5
source share
3 answers

In my opinion, the static variable inside the function should be initialized even before main ()

Your mind is wrong ... at least in part. A static local variable can be initialized early in some situations, but not when the constructor depends on a local variable such as this.

n3242 draft standard Β§6.7 / 4:

... Implementation is allowed for early initialization of other variables of a block area with static or stream storages under the same conditions that implementations are allowed to statically initialize a variable with statics or duration of storage of streams in the namespace (3.6.2). Otherwise, such a variable is initialized when the first control passes through its declaration; ...

For completeness, here are the requirements for constant (static) initialization Β§ 3.3.2 / 2:

Continuous initialization is performed:

- if every complete expression (including implicit conversions) that appears in the link initializer with a static or storage duration of streams is a constant expression (5.19), and the link is bound to the value lvalue, the destination of the object with a static storage time or temporary (see 12.2);

- if the object with the statics or the duration of the storage of the stream is initialized by calling the constructor, if the constructor is constructor constexpr, if all the constructor arguments are constant expressions (including conversions), and if, after substituting the function call (7.1.5), each constructor call and the full expression in mem- initializers is a constant expression;

- if the object with the statics or duration of the storage of the stream is not initialized by calling the constructor, and if each complete expression that appears in its initializer is a constant expression.

1) x initialized when execution reaches its declaration for the first time and that when the constructor starts. So b fully initialized when x initializes.

2) Regarding initialization dependencies, yes.

3) Of course, if you need it, the constructor of a static local object may depend on the local object. Until you refer to this local object after its absence. In this case, you simply copy it, so you will not depend on it after building x .

+3
source

According to C ++ standard (expression on declaration 6.7)

4 Zero initialization (8.5) of all variables of a block area with a static storage duration (3.7.1) or a storage duration of flows (3.7.2) before any other initialization .... Otherwise, such a variable is initialized when the first time control passes through his expression; such a variable is considered initialized to complete its initialization. If the initialization completes the exception, the initialization is not completed, so it will try again when the next time the control enters the declaration ....

Thus, before the function receives control, local static variables are initialized to zero, and then, when the function receives the control, they are initialized using their initializers (or constructors).

+1
source

Vlad did the hard part of finding links in the C ++ standard.

Now for your questions:

  • when the constructor x ? will be executed: for every Vlad’s answer, it will be executed the first time you call f , and x will save its value through any other call
  • Is this really a working program ?: the current program is not a compiler, but for other errors: x and y are private in the bar, and in f , x already a parameter. But initializing a static variable with the values ​​passed in the first call is fine.
  • Is this good practice ?: this is not a common distribution, so it needs to be explained in a comment for the following readers or companions. Also, nothing happened to him if you know why you are using this construct.
0
source

All Articles