使用静态变量会导致链接器错误

时间:2014-08-14 12:43:00

标签: c++ static linker-errors

编译时,我的代码出现以下错误:

Undefined symbols for architecture x86_64:
  "A::MyNumber", referenced from:
      B::setValue(double) in B.o
ld: symbol(s) not found for architecture x86_64

A的头文件中:

public:
    static double MyNumber;

A的类文件中,位于任何函数之外的构造函数之上:

double A::MyNumber = 1.0;

B' setValue()函数中:

#include "A.h"

void B::setValue(double val)
{
    double newVal = val * A::MyNumber;

    ...
}

我很难过......我在使用静态变量的项目中查看了其他示例,并尽力确保我做到了正确。我唯一能想到的是A位于由B项目链接的库中。

1 个答案:

答案 0 :(得分:2)

您犯了一个典型的错误,就是不要告诉链接器可见性。如果您创建库,则需要公开所谓的库符号。检查的最简单方法是使用这样的nm实用程序(-g表示 - 仅显示外部符号):

nm -g <your library>

解决方案非常简单,但从编译器到编译器各不相同。对于GCC / CLang,它是属性,但几乎所有支持 extern 。典型用法在顶级配置文件中的某处显示:

#if COMPILER_HAS_ATTR_HIDDEN_VISIBILITY   // GCC with -fvisibility=hidden
#define PUBLIC_API            __attribute__((visibility("default")))
#define PRIVATE_API           __attribute__((visibility("hidden")))
#elseif COMPILER_HAS_DECLSPEC_VISIBILITY  // Microsoft C++
#define PUBLIC_API            __declspec(dllexport)
#define PRIVATE_API
#else
#define PUBLIC_API            extern
#define PRIVATE_API
#endif

现在重新宣布你的班级:

// Exposed class
class PUBLIC_API A
{

};

另一个问题是如何使用您的构建工具链来检测它,但这超出了您的问题范围。为了快速证明 - 在您的类声明中添加extern关键字并重建库。