如果未链接使用代码,则未定义对 g++ 中静态常量成员的引用

Undefined reference to static const member in g++ if no using code is linked

我目前正在处理的项目包含三个基本构建目标:

linking 错误仅在我构建客户端时出现。它是关于核心中的静态常量,看起来像这样:

class Transition
{
private:
  Transition();
  ...more declarations...

public:
  static const Transition NO_TRANSITION
  ...more declarations...
}

在Map.cpp中的用法:

Transition Map::searchTransition(Coordinate p, Direction d)
{
  ...code...
  return Transition::NO_TRANSITION;
}

这是 g++ 告诉我的:

obj/gpp/Debug/Game/Map/Map.o:Map.cpp: (.rdata$.refptr._ZN10Transition13NO_TRANSIT IONE[.refptr._ZN10Transition13NO_TRANSITIONE]+0x0): 未定义引用`Transition::NO_TRANSITION'

Map.cpp 也是核心的一部分,它包括 Transition.h,并且 .o 文件就在预期的位置。两个涉及的文件之间没有前向声明。

最让我困扰的是:只有在我构建客户端时才会发生这种情况。如果我 link 核心与测试 类 而不是它们的主要部分,它工作得很好,这意味着只有更多代码需要 linked。唯一删除的是一个很小甚至是空的主函数,它被一个实际使用 Map 和 Transition 的大得多的函数所取代。

此外,static const 不是新的,过去从未引起过问题。由于测试接受了它,我认为一切都很好,但显然只要测试linked 就可以了。

我已经尝试在一个较小的项目中重现错误,生成文件(大部分)相同,但错误不会出现。我完全不知道重要的区别是什么。

我在 cygwin 下使用 g++ 4.8 和 -std=c++11。 Visual Studio 可以毫无问题地接受相同的代码,并且在 true linux 下我还不能测试,尽管我希望它与 cygwin 相同。

有人知道这里可能出了什么问题吗?

编辑:"strange" 行为的发生是因为在测试中实际上有一个 Transition::NO_TRANSITION 的定义。

您必须定义静态变量。在您的 CPP 中,添加此行。

static const Transition::Transition NO_TRANSITION

那就行了。

您只是声明了它,因此没有存储其数据的物理位置。您应该将定义添加到您的 Transition 源和 link 使用您的测试创建的目标文件。

// Transition.cpp
#include "transition.h"
const Transition Transition::NO_TRANSITION;

请注意,linker 以某种方式延迟工作,即不会搜索您未引用的符号,因此未使用实际 NO_TRANSITION 物理位置的旧代码已编译并link很好。