【问题标题】:extern variable resets itself in visual studio [duplicate]外部变量在Visual Studio中自行重置[重复]
【发布时间】:2023-04-01 14:29:01
【问题描述】:

考虑以下示例:

// 头文件props.h

#pragma once
#include <vector>
extern std::vector<int> prop;
struct addToVec
{
    addToVec(int a)
    {
        prop.push_back(a);
    }
};

// cpp文件props.cpp

#include "props.h"
std::vector<int> prop;
addToVec b(10);

// main.cpp

#include <iostream>
#include "props.h"
addToVec a2(14);
int main(int argc, char** argv)
{
    std::cout << prop.size();
    return 0;
}

预期输出为 2。但实际输出为 1。

这给出了 gcc 编译器的预期结果 (2)(不确定版本)。我正在使用 Visual Studio Professional 2013 版本 12 更新 5。这是错误还是预期结果?

元素添加到向量中的顺序与我无关。我唯一担心的是向量中只添加了一个元素(而不是 2 个)。

【问题讨论】:

  • 元素添加到向量的顺序与我无关。我唯一担心的是向量中只添加了一个元素(而不是 2 个)。
  • 重要的顺序是prop是在addToVec的实例之前还是之后创建的。

标签: c++ global-variables extern


【解决方案1】:

要对抗静态初始化排序,您可以使用带有静态成员的函数:

// header props.h

#pragma once
#include <vector>
std::vector<int>& getProp();
struct addToVec
{
    addToVec(int a)
    {
        getProp().push_back(a);
    }
};

// cpp file props.cpp

#include "props.h"
std::vector<int>& getProp(){
    static std::vector<int> prop;
    return prop;
}
addToVec b(10);

这样prop只会在需要的时候创建。

【讨论】:

    【解决方案2】:

    这是“静态初始化订单惨败”的一个实例 - 参见例如static initialization order fiasco.

    非本地对象的初始化顺序在 C++ 中没有定义,因此在这种情况下,您不能依赖 prop 与 a2 的初始化顺序。您必须选择一个(或两个)在您的控制下显式初始化,而不是依赖未定义的顺序。

    【讨论】:

      【解决方案3】:

      虽然在单个 translation unit 中明确定义了初始化顺序,但它没有在翻译单元之间定义。

      这意味着您无法控制 prop 是在 a2 之前还是之后构造和初始化

      避免使用全局变量的另一个原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-06
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        相关资源
        最近更新 更多