要小心 C++ 静态初始化顺序

https://godbolt.org/z/n5bjMGcx3

编译器并不会自动根据代码的依赖关系去编排静态初始化顺序,示例代码中 vec 在被推入两个元素之后又被初始化了一次(在 compiler explorer 中看汇编也能看出来)。

#include <iostream>
#include <vector>

extern std::vector<int> vec;

void report_size() {
    printf("vec.size(): %zd\n", vec.size());
}

auto _1 = []() {
    vec.push_back(0);
    printf("first  ");
    report_size();
    return 0;
}();

auto _2 = []() {
    vec.push_back(0);
    printf("second ");
    report_size();
    return 0;
}();

std::vector<int> vec;

int main() {
    printf("main   ");
    report_size();
}

输出:

first  vec.size(): 1
second vec.size(): 2
main   vec.size(): 0

在这个测试中,各个变量看起来是按照定义顺序初始化的。遇到多个目标文件链接的情况,初始化顺序就不太好控制了。必要时使用 41 共享库基础 - 个人回忆 中描述的懒初始化方法。