使用clang内置函数的好处与使用标准函数相比有什么优势?

5

Clang和GCC定义了一堆内建函数,我将在此处使用remainder作为示例:

__builtin_sqrt(x)

然而,标准C99在math.h中定义了以下内容。
sqrt(x)

clang为什么要定义一个已经存在的方法的内置函数呢?我认为像sqrt这样的常见数学函数应该由后端进行优化,因此不需要内置函数。这些内置函数比标准c更不可移植,原因显而易见。

1
你不应该直接使用__builtin_sqrt。你应该使用sqrt。编译器会识别sqrt是一个已知的函数,并将其替换为__builtin_sqrt。在实现这个功能时,gcc没有内部函数的概念,它只有内置函数,这些函数对用户可用,因此__builtin_sqrt最终可以在用户代码中工作,但这只是历史上的偶然事件。 - Marc Glisse
@MarcGlisse 为什么不直接使用它?甚至不用 #ifdef 来获取编译器特定的内置函数?如果不是,为什么不呢? - SO_fix_the_vote_sorting_bug
1
@jdk1.0 为什么要使用更长、不可移植的代码,而标准代码是等效的呢? - Marc Glisse
1个回答

6

来自gcc手册

GCC通常会生成特殊的代码以更高效地处理某些内置函数;例如,对于alloca的调用可能会变成直接调整堆栈的单个指令,而对于memcpy的调用可能会变成内联复制循环。生成的代码通常既更小又更快,但由于函数调用不再像原来那样出现,因此您无法在这些调用上设置断点,也无法通过链接到不同的库来更改函数的行为。此外,当一个函数被识别为内置函数时,GCC可以使用关于该函数的信息来警告有关对该函数的调用存在问题的情况,或者生成更高效的代码,即使生成的代码仍然包含对该函数的调用。例如,在printf内置且strlen已知不修改全局内存时,使用-Wformat会给出有关对printf的错误调用的警告。

库函数是编译器外部的,因此它不能像内建函数那样对它们进行推理。例如,编译器可以在常量折叠中使用内建函数,例如用1替换__builtin_sqrt(1),但通常无法对调用库函数sqrt(1)进行相同的操作。

使用内建函数不会影响可移植性,因为它们实现了标准C,所以具有相同的语义。


@MarcGlisse 因为它用 __builtin_sqrt 替换了它。 - el.pescado - нет войне
看起来 GCC 在 -O3 优化选项下有相同的结果:https://godbolt.org/g/J1ztkQ - H Bellamy
我要取消接受这个答案,因为它的前提似乎是不正确的? - H Bellamy
我已经更新了我的答案,包括从gcc文档中更好的引用。 - el.pescado - нет войне

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接