c - -O0 处的内联函数导致 clang 中的链接失败

标签 c optimization clang inline c99

<分区>

我正在尝试在各种优化级别使用 clang 编译以下代码:

#include <stdio.h>

inline int foo() { return 42; }

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

-O1-O2-O3-Os处编译成功,但是使用 -O0 时失败:

$ clang -O0 -o main main.c
Undefined symbols for architecture x86_64:
  "_foo", referenced from:
      _main in main-8b9319.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

-O0 处的故障(和解决方法)可以用 Clang's inline compatibility 来解释,但是无论优化级别如何,我都会天真地期望它会失败。似乎在 -O1 及以上启用的一些优化正在做一些事情来防止发生此链接错误,但我很好奇它们是哪些优化以及为什么它们似乎具有与使用不同的语义inline 单独在 -O0

最佳答案

-O1 和更高版本中,它不会调用函数,它只是将代码移动到 main 中,我们可以通过使用 godbolt 看到这一点显示如下的 asm see it live :

main:                                   # @main
  pushq %rax
  movl  $.L.str, %edi
  movl  $42, %esi
  xorl  %eax, %eax
  callq printf
  xorl  %eax, %eax
  popq  %rdx
  retq

reference says 是什么:

[...]because if add isn't inlined (for example, when compiling without optimization), then main will have an unresolved reference to that other definition[...]

这包含在草案 C99 标准部分 6.7.4 函数说明符中:

Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.122)

本站对语言有很好的解释:The tricky inline specifier in C99

关于c - -O0 处的内联函数导致 clang 中的链接失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30516423/

相关文章:

.net - 生成 4x4x4 数独板的更好/好方法?

c++ - Clang 运行时检查 : print backtrace

c - 最长的字符串

c - 如何将结构成员定义为其他成员的总和

c - 未找到 libtool 命令

Clang 解析器 - 忽略指令 #ifdef,解析所有内容

c++ - 为什么我从 gdbserver 得到 "not in executable format: Success",但在 gdb 中一切正常?

c - 提高屏幕捕获性能

regex - 如何优化使用正则表达式和for循环编写的python代码?

c++ - 使用 dlib 的成员函数指针未在此范围内声明