gpt4 book ai didi

c++ - 在 main 之前使用来自不同文件的变量

转载 作者:行者123 更新时间:2023-11-30 03:47:32 24 4
gpt4 key购买 nike

我有点难以理解为什么我的代码按它的方式工作(或者不按它应该的方式工作)。

我正在尝试编写(在 C++ 中)一个接口(interface),该接口(interface)允许使用 C 中标准模板库中对 unordered_map 进行操作的一些函数。但是,我还想编写一个命名空间这也允许在 C++ 中使用它们。

我要问的不是如何以不同的方式实现它,而是为什么它会以这种方式工作;

假设我只需要两个功能:添加元素和写入 map 的大小。 header 如下:

//project.h
#ifdef __cplusplus
extern "C" {
#endif

void add(int, int);

void give_size();

#ifdef __cplusplus
}
#endif

源代码:

//project.cc
#include <unordered_map>
#include <iostream>
#include "project.h"

using namespace std;

unordered_map<int, int> my_map;

void add(int arg, int val) {
my_map.insert ({{arg, val}});
}

void give_size() {
cout << my_map.size() << endl;
}

C++ 接口(interface):

//cproject
namespace pro {
#include "project.h"
}

和一个测试:

//test.cc
#include "cproject"
namespace {
unsigned long test() {
::pro::add(1,2);
::pro::add(3,4);
return 0;
}
unsigned long dummy = test();
}
int main() {
::pro::give_size();
return 0;
}

并且,为了完整起见,Makefile:

g++ -Wall -std=c++11 -c -o project.o project.cc
g++ -Wall -std=c++11 -c -o test.o test.cc
g++ test.o project.o -o test

当然,问题是运行 test 输出 0 而不是 2 - 这意味着 map 在 之前的某处消失了code>testmain.

我在想它可能是某种 static initialization order fiasco ,但是我没有发现附加的解决方案非常有用,因为我没有在 test.cc 中显式调用 project.cc 文件中的对象。

如果您能帮助我解决这个问题,我将不胜感激。

最佳答案

是的,这是命名不当的静态初始化顺序的失败。命名不当,因为 C++ 标准称它为“动态初始化”; “静态初始化”是不同的东西。

which means that the map disappears somewhere before the test's main

不完全是。问题是您在它存在之前就使用了 map ,向它添加了值。现在碰巧对于某些 map 实现,零初始化状态(这是在任何动态初始化程序运行之前对所有全局变量所做的)与默认构造函数所做的相同。所以 test 中的代码首先被执行并尝试向 map 添加东西, map 的插入功能工作得很好,创建节点,设置节点的内部指针等。

然后 map 的实际默认构造函数运行,将这些指针重置为空,泄漏并忘记您创建的所有节点。您之前的插入已撤消, map 再次为空。

您链接中提供的解决方案会起作用;你通过自由函数隐式地调用对象,即使你没有明确地这样做。没有真正的区别。您仍将 project.cc 中的全局 my_map 替换为返回对函数级静态(或指针,具体取决于您选择的确切解决方案)的引用的函数。唯一的区别是您不是从 test.cc 中调用此函数,而是从 addgive_size 中调用。

作为旁注,整个全局状态的事情通常是相当可疑的。它不是线程安全的,并且使理解程序正在做什么变得更加困难。考虑完全不这样做。

关于c++ - 在 main 之前使用来自不同文件的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33655645/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com