C ++ - non-local static object and local static object

Concerning the book "Effective C ++" by Scot Meyers and the fourth point: non-local static objects can be uninitialized before they are used (static in this case means "global", with a static lifetime). If you replace it with a local static object, which is created inside a function that returns a link to it, then the object will be necessarily initialized before use.

I always have a file with constants. I declare extern const int a; in the .hpp file and define it in the .cpp file. But then, could the same thing happen? a may be uninitialized. Or not? Is the same rule used for built-in types?

+5
source share
2 answers

Even if you can, it is not such a good idea to return references to "locally static" variables. This variable was (allegedly) declared locally in order to reduce its scope to only an incoming function, so trying to increase its scope in this way is pretty negligent. You can make it a global variable and use something like std :: call_once to guarantee that it is initialized exactly once upon first use. Returning a volatile reference to a locally static object also causes thread safety issues because the function can no longer be re-enabled.

POD types with static storage duration guarantee zero initialization. You can also initialize them with a constant expression, and the language ensures that they are initialized before any dynamic initialization begins. Here is a similar question that may provide additional information.

+2
source

The static initialization problem is known as the static initialization of the fiasco order :

In short, suppose you have two static objects x and y that exist in separate source files, say x.cpp and y.cpp. Suppose further that initialization for an object y (usually a constructor of y-objects) calls some method for an object x.

So, if you have another translation unit using your constants, you have a pretty good chance that your program will not work. Sometimes it’s that the files are linked to each other, some formats even define it in the document (I think Solaris is one example here).

The problem also applies to built-in types such as int. Example from the FAQ:

 #include <iostream> int f(); // forward declaration int g(); // forward declaration int x = f(); int y = g(); int f() { std::cout << "using 'y' (which is " << y << ")\n"; return 3*y + 7; } int g() { std::cout << "initializing 'y'\n"; return 5; } int main() { std::cout << x << std::endl << y << std::endl; return 0; } 

If you run this example, the output will be:

using 'y' (which is 0) initializing 'y'

So y first gets zero initialization, and then constant initialization (?) Is done.

The solution is Build the first time you use the idiom :

The main idea of ​​Constio on First Use Idiom is to wrap a static object inside a function.

Static local objects are created when the control flow is first accessed.

0
source

Source: https://habr.com/ru/post/1264557/


All Articles