Fundamentals 28 min read

Unraveling C++ static: From Variables to Destruction Order

This article explains the many roles of the C++ static keyword—how it affects variables, functions and class members—then dives deep into static object lifetimes, destructor rules, destruction order across translation units, common pitfalls such as resource‑dependency bugs, memory leaks and multithreading issues, and finally offers practical solutions and interview‑style questions.

Deepin Linux
Deepin Linux
Deepin Linux
Unraveling C++ static: From Variables to Destruction Order

1. Overview of the static keyword

In C++ the static specifier can be applied to variables, functions and class members, giving them static storage duration, internal linkage or class‑wide sharing.

1.1 Static variables

Static local variables retain their value between function calls, e.g.:

void countFunctionCalls() {
    static int callCount = 0;
    ++callCount;
    std::cout << "called " << callCount << " times
";
}

Static global variables are limited to the translation unit, preventing name clashes.

Static class members are shared by all objects of the class and must be defined outside the class.

class MyClass {
public:
    static int sharedValue;
};
int MyClass::sharedValue = 0;

2. Static destructors – principles and rules

A destructor runs when an object’s lifetime ends, releasing resources. Static objects (both global and local) are destroyed when the program terminates, in the reverse order of their construction.

2.1 When are destructors called?

Local objects – at the end of their scope.

Static local and global objects – at program exit.

Dynamically allocated objects – when delete is executed.

2.2 Characteristics of destructors

Destructors have no parameters, no return type, and a class can have only one. The compiler generates a default one if none is provided.

2.3 Destruction order of static objects

Within a single translation unit, static objects are destroyed in the opposite order of construction. Across multiple files the order is undefined, which can cause resource‑dependency bugs.

3. Common pitfalls

Incorrect order leading to use‑after‑free (e.g., OceanBase session object accessing an already‑destroyed allocator).

Memory leaks when a static pointer owns dynamic memory but the destructor does not free it.

Data races in multithreaded code that modifies a static variable without synchronization.

4. Solutions

Force construction order by accessing dependent static objects early.

Use smart pointers ( std::unique_ptr, std::shared_ptr) to manage dynamic resources.

Protect static data with std::mutex or thread‑local storage.

5. Interview questions

Typical questions cover destruction order of global vs. local static objects, behavior in multi‑file programs, and the effect of atexit registration.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cstaticdestructorinitialization-orderobject lifetime
Deepin Linux
Written by

Deepin Linux

Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.