首页 > 解决方案 > 为什么在 C 程序中内联函数时会出现与 clang 的链接错误?

问题描述

为什么以下程序不能用 clang 编译?

#include <stdio.h>

inline int f() {
  return 42;
}

int main() {
  printf("%d\n", f());
}

我得到以下信息:

$ clang -o inline inline.c
Undefined symbols for architecture arm64:
  "_f", referenced from:
      _main in inline-975155.o
ld: symbol(s) not found for architecture arm64
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)

但是我可以用clang++编译它就好了。inlineC 与 C++之间是否存在细微差别?

标签: cclanginline

解决方案


在 C99 中,当编译器无法内联时,您需要提供函数的替代(非内联)定义。见https://clang.llvm.org/compatibility.html#inline

一种可能对您有用的解决方案是将定义设为静态:

#include <stdio.h>

static inline int f() {
  return 42;
}

int main() {
  printf("%d\n", f());
}

将按您的预期工作。

clang以下是链接页面上列出的所有选项:

  • 更改添加到静态内联函数。如果只有一个翻译单元需要使用该功能,这通常是正确的解决方案。静态内联函数总是在翻译单元中解析,因此您不必在程序的其他地方添加函数的非内联定义。
  • 从此定义中删除 inline 关键字f。内联函数不需要 inline 关键字,也不保证一定会这样。一些编译器完全忽略它。Clang 将其视为程序员的温和建议。
  • f提供程序中其他地方的外部(非内联)定义。这两个定义必须是等价的!
  • 通过将 -std=gnu89 添加到 Clang 选项集以编译 GNU C89 方言。仅当程序源无法更改或程序还依赖于无法更改的其他 C89 特定行为时,才建议使用此选项。

推荐阅读