首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >名称空间中的C++全局变量

名称空间中的C++全局变量
EN

Stack Overflow用户
提问于 2016-04-14 11:18:32
回答 2查看 14.4K关注 0票数 0

我在这方面看到了很多问题,但没有一个问题包括如何为这个特定的用例编译代码。我运行以下命令:g++ main.cpp c.cpp testobj.cpp -o main,但是运行它会给出一个Segmentation fault (core dumped)。当我在main方法中使用main.cpp中的print语句并删除所有TestObj代码时,它就工作了。

这是分配C::test常量的正确方法吗?

main.cpp:

代码语言:javascript
运行
复制
#include "c.h"
#include "testobj.h"

TestObj testobj;

int main() {
    return 0;
}

c.h:

代码语言:javascript
运行
复制
#ifndef CONSTANTS
#define CONSTANTS

#include <string>

namespace C {
    extern std::string test;
}
#endif

c.cpp:

代码语言:javascript
运行
复制
#include "c.h"

namespace C {
    std::string test = "test";
}

testobj.h:

代码语言:javascript
运行
复制
#ifndef TESTOBJ
#define TESTOBJ

class TestObj {
public:
    TestObj();
};

#endif

testobj.cpp:

代码语言:javascript
运行
复制
#include "testobj.h"
#include <iostream>
#include "c.h"

TestObj::TestObj() {
    std::cout << C::test << std::endl;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-14 11:25:02

虽然单个https://en.wikipedia.org/wiki/Translation_unit_%28programming%29中全局变量的初始化顺序定义得很好,但转换单元之间的顺序却不是这样。

因此,如果testobj源文件中的main.cpp对象是在C::test对象之前初始化的,那么您确实会有奇怪的行为。

如果您有多个转换单元,每个单元都有全局变量,那么您就不能依赖它们之间的初始化顺序。

票数 2
EN

Stack Overflow用户

发布于 2016-04-14 11:28:55

这是由全局静态变量的初始化顺序造成的。它是未定义的,被称为静态初始化顺序失败。当TestObj::TestObj(使用C::test时,它还没有被构造。

解决该问题的常用方法是将全局静态变量移动到函数本地静态变量中,即:

代码语言:javascript
运行
复制
const std::string getTestString() {
    static std::string test = "test";
    return test;
}

现在,当您调用getTestString()时,测试变量将被构造,并且它将精确地完成一次。另外,由于函数中静态变量的C++11初始化是线程安全的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36621501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档