访问静态成员函数给出:ld: 找不到体系结构的符号 x86_64

Accessing static member function gives: ld: symbol(s) not found for architecture x86_64

我确定这是一个菜鸟 C++ 问题,只是反映了我的理解不足。

我有一个文件

A.cxx包含,

#include "Rishab.h"
#include <future>

void functionToRun() {
  while (true) {
    Rishab::hello();
  }
}

int main() {
    std::future<void> futureVariable = std::async(std::launch::async, functionToRun);
}

Rishab.h

#ifndef __METRIC_RISHAB_H__
#define __METRIC_RISHAB_H__

class Rishab {
public:
    static void hello();

};
#endif

Rishab.cxx

#include "Rishab.h"

void Rishab::hello() {
}

当我尝试编译它时,链接器抛出错误,

Undefined symbols for architecture x86_64:
  "Rishab::hello()", referenced from:
      functionToRun() in A.cxx.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

PS: 这些文件是一个更大项目的一部分,所以有一个 Makefile。

我已经在网上查看了其他答案,但大多数答案都迎合了 static variable 未定义(且仅声明)的问题。但我的问题涉及static function

错误消息告诉您 linker 在尝试为每个 翻译单元[=37= 组合所有 separately-compiled object 代码时](即包含源代码的每个文件),它无法解析函数 void Rishab::hello().

的存在

这很可能意味着您实际上并没有提供编译后的 Rishab.cxx 文件中的 object 代码作为您对 linker 调用的一部分。因此,linker 不知道在哪里可以找到该函数的实现,因此它不能 assemble 一个完整的程序。

请注意,header(通常称为 接口 )是声明可以跨源文件共享的符号(通常称为 实施):

  • 在编译时,每个单独的源文件只需要知道接口。可以免费使用这些接口,而无需担心它们是如何实现的。这就是允许将程序分成许多不同部分的原因,而不必一次性编译所有内容。简单来说,您的界面为实际编译的代码创建占位符。

  • 在 link 时,所有编译的部分必须连接在一起,所有接口必须解析为它们的实现。如果 linker 找不到实现,那就是错误。

任何时候您看到这样的符号解析错误,最可能的原因是:

  • 您忘记定义在 header
  • 中声明的内容
  • 您在声明或定义中打错了字
  • 您使用的命名空间不正确
  • 你忘了告诉 linker 它需要知道的一切(例如 给它所有相关的 object 文件)
  • 您正在使用您的 object 文件之一的 stale/outdated 版本(也许您没有注意到编译失败,并且您尝试 link 无论如何)