【问题标题】:static variable resolution at build time构建时的静态变量分辨率
【发布时间】:2012-01-05 21:08:21
【问题描述】:

我有链接在一起的文件:

基本.h

#pragma once

extern const string APPLICATION_NAME;

应用程序.cpp

#include "basic.h"

const string APPLICATION_NAME = "MyApplication";

............

ErrorTables.h

class ErrorTable
{
public:
    ErrorTable();

private:
    map <index, errorRecord> _errorTable;


};

ErrorTables.cpp

#include "basic.h"

ErrorTable TheErrorTable;

ErrorTable::ErrorTable()
{
   ...
   _errorTable[errorIndex] = errorRecord(APPLICATION_NAME + " hit some error.");
   ...
}

此代码可以在 Visual Studio 中构建和运行。 当我使用 GCC 时,它可以构建但在运行时失败。 问题出在具有静态链接的 TheErrorTable 中,并且是 在 main() 启动之前创建;它无法解析 APPLICATION_NAME 变量。 如果我使用局部变量隐藏它,一切正常。

是否有 GCC 标志在构建期间强制解析静态变量或 以其他方式实现 Visual Studio 的行为?

【问题讨论】:

  • 你能发布你用来构建它的g++ 命令(不是gcc)吗?
  • 哎呀。该链接读起来更像是“幽默”/咆哮,而不是常见问题解答或严重的语言批评。

标签: c++ gcc


【解决方案1】:

问题出在TheErrorTable 中,它具有静态链接并且是在 main() 启动之前创建的;它无法解析APPLICATION_NAME 变量。

没错。 要么 TheErrorTable 要么 APPLICATION_NAME 被先初始化,你无法解决这个问题。


使ErrorTable 成为一个全球性的。您无法定义跨 TU 的静态初始化顺序,即使可以,您也只能让代码更难遵循。

我不想这么说,但ErrorTable 可能会从这里的单例模式中受益(因为函数-statics 具有合理的初始化顺序),至少在它是最接近您现有代码的解决方案方面。


更新

正如@godexsoft 所暗示的,您可以通过利用常量初始化 并将APPLICATION_NAME 设置为char const* 而不是std::string 来解决此问题;然后,您的初始化程序将是一个没有构造函数调用的常量表达式初始化程序,因此将在任何 ErrorTable 之前被调用——跨 TU——保证。 (Really? Yes.)

【讨论】:

  • +1 我认为用返回相同字符串的函数替换 APPLICATION_NAME 也会纠正这个问题?
  • @hmjd:是的,只要字符串是该函数的本地字符串,也可以这样做。这本质上就像让APPLICATION_NAME 成为迷你单例;)
  • 或者只是将其设为 char*,这将强制它在任何非 POD 之前被初始化(对于静态全局变量为 true)。
  • @godexsoft:真的吗?我没有意识到这一点。你能提供一个引用吗?
  • @LightnessRacesinOrbit 是的.. 我过去偶然发现了这一点,从那以后就记住了:-) 我实际上找不到引用..
猜你喜欢
  • 1970-01-01
  • 2018-04-29
  • 2019-11-26
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多