【问题标题】:Using compiler builtins without linking the c standard library在不链接 c 标准库的情况下使用编译器内置函数
【发布时间】:2020-05-21 22:03:38
【问题描述】:

我见过this question,他的回答得出的结论是内置数学函数(如__builtin_sin__builtin_fmod 等)可以替换C 标准库中的函数。

我写了以下程序:

float fmod_test(float arg1, float arg2) {
    return __builtin_fmod(arg1, arg2)
}

void _start() {}

并编译如下:

gcc -nostdlib test.c -o test

很遗憾,我收到以下错误:

/tmp/ccuHpvCP.o: In function `fmod_test':
test.c:(.text+0x1d): undefined reference to `fmod'
collect2: error: ld returned 1 exit status

似乎__builtin_fmod 在后台使用fmod 并需要链接到它,而不是像“内置”函数那样生成内联版本。

有没有办法在不链接外部库的情况下使用这些内置函数?

【问题讨论】:

    标签: c libc


    【解决方案1】:

    这个问题的答案取决于您使用的是哪个 C 编译器。您似乎在使用 GCC;该编译器的答案是否定的。

    这些函数是“内置”的,因为 GCC 知道它们的名称并且可以优化对它们的一些调用,例如fmod(7.0, 2.0) 很可能在编译时进行评估。但是 GCC 不提供这些函数的运行时定义。它依赖于 C 库(这是一个单独的项目)来提供它们。

    【讨论】:

    • 说 GCC 不提供运行时定义可能过于宽泛。它可能适用于某些体系结构,至少在提供指令的意义上,而不适用于其他体系结构,它可能适用于某些参数(例如,其中一个是函数更容易计算的常数)而不是其他参数。
    【解决方案2】:

    正如the gcc manual 所说:

    其中许多功能仅在某些情况下进行了优化;如果它们在特定情况下未优化,则会发出对库函数的调用。

    因此没有保证方法可以避免调用库函数的可能性。

    但是,您可以尝试调用函数的方式和优化选项,以期找到可以内联的组合。特别是,对于浮点内置函数,gcc 通常只会在 -ffast-math 生效时内联它们,因为它的内联代码可能无法达到尽可能高的精度或处理所有极端情况(NaN、无穷大、非正规、设置 errno 等) 就像精心编写的库函数一样。这里就是这种情况,事实上,如果你启用-ffast-math,你会得到内联代码:see on godbolt。 (开启优化会更好看。)

    当然,如果您稍后更改编译器选项,或以不同的方式调用函数,或切换到不同的编译器版本,编译器可能会再次发出库调用。您会知道是否会发生这种情况,因为您的程序不会链接,因此至少它不会静默中断,然后您可以尝试重新调整您的代码和/或编译选项,或者如果需要,编写或导入您自己的版本的功能。

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      相关资源
      最近更新 更多