【问题标题】:C++ Global class variables are not created未创建 C++ 全局类变量
【发布时间】:2010-11-18 19:11:02
【问题描述】:

我正在查看一段创建全局类变量的代码。这些类的构造函数调用一个符号表单例并在其中添加 this 指针..

在关键字.cpp 文件中

class A : class KeyWord
{
  A() { add(); }
} A def;

对于关键字 B、C 等类似

void KeyWord::add()
{
 CSymbolCtrl& c = CSymbolCtrl::GetInstance();
 c.addToTable(this);
}

这些翻译单元被编译成一个库。当我“转储”库时,我看到了 ADef、BDef 等的动态初始化程序。

在 exe 中没有,当我调用 CSymbolCtrl 实例时,我没有找到存储在其映射中的 ADef、BDef..。当我在 add() 中设置断点时,它没有被命中。有没有办法让链接器忽略 ADef、BDef,因为它们在任何地方都没有被引用?

}

【问题讨论】:

  • 你能使用合理编译的示例代码吗?

标签: c++ global-variables


【解决方案1】:

来自标准文档1.9 程序执行

4) 该条款有时被称为“as-if”规则,因为实施可以随意忽略本国际标准的任何要求 只要结果好像满足了要求,就可以从程序的可观察行为中确定。例如, 如果一个实际的实现可以推断出它的值未被使用并且没有影响表达式的副作用,则它不需要评估表达式的一部分 产生了程序的可观察行为。

所以,它可能,是的。

【讨论】:

    【解决方案2】:

    简短的回答是肯定的。强制注册的一种非常常见的方法是执行以下操作:

    static bool foo = register_type();
    

    【讨论】:

    • 有没有办法强制链接器不要忽略这些变量?
    • @user97642:在相关的翻译单元中,添加一些功能即可。调用该函数。这听起来像是魔术,但标准要求在调用之前初始化静态变量,因此它引入了依赖项。干杯&hth.,
    • @Alf P. Steinbach,像def; 这样的空用法还不够吗?或者它确实需要从中调用一个函数?
    • @liaK: C++98 §3.6.2/3 说(在注意到它的实现定义是否在main 的第一个语句之前完成初始化之后):“如果初始化被推迟到某个在main 的第一条语句之后的点,它应该发生在与要初始化的对象在同一翻译单元中定义的任何函数或对象的第一次使用之前”。所以按照标准,你会在安全的基础上。但我只是有一种直觉,编译器可能会错误地优化掉对对象的空引用,所以我会使用一个函数。干杯&hth.,
    • @Alf P. Steinbach,是的,没错。但我认为在这种情况下,只是为了使用,定义一个函数似乎很奇怪。虽然海事组织... :)
    【解决方案3】:

    你的问题不太清楚,但你真的是 是否在您的链接中包含已编译的目标文件?只是 将文件放入库中不会导致它被包含在 最后的程序。根据定义,来自库的文件将 仅在解决未解决的问题时才包含在可执行文件中 外部符号。如果您希望目标文件成为 最终的可执行文件,它不包含任何全局变量 解决一个未定义的外部,那么你有几个选择:

    -- 直接链接目标文件,而不是放入 图书馆。 (这是“标准”或“规范”的方式 这样做。)

    -- 使用 DLL。不管这个名字,DLL 不是库,而是 目标文件,并以全有或全无的方式链接。

    -- 创建一个虚拟全局符号,并在某处引用它。 (这通常可以自动化,并且可能是首选 如果您作为第三方提供库,则解决方案 供应商。)

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 2017-11-12
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多