gpt4 book ai didi

c - sqrt 仅在参数为非负时定义

转载 作者:太空狗 更新时间:2023-10-29 15:14:58 25 4
gpt4 key购买 nike

这样编译很好

#include <math.h>

int main(void) {
double i = sqrt(9.0);
}

如果我将 9.0 更改为 -9.0,那么我的编译器 (GNU C) 会给出一个关于对“sqrt”的 undefined reference 的错误。

我原以为 sqrt 函数会返回 NaN 或异常。 C 库如何只为非负参数定义 sqrt?

最佳答案

这是因为 gcc 可以在优化过程中使用 内置函数 在编译时计算某些函数,包括 sqrt所有情况。如果是这种情况,它将不需要发出对 sqrt 的调用,因此不需要链接到 libm

gcc 文档有一个 complete list of builtins ,它说(强调我的):

The remaining functions are provided for optimization purposes.

GCC includes built-in versions of many of the functions in the standard C library. The versions prefixed with _builtin are always treated as having the same meaning as the C library function even if you specify the -fno-builtin option. (see C Dialect Options) Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.

如果我使用 gcc -S 编译此代码并查看我们使用 sqrt(9.0) 时发出的程序集 ( live example ) > 然后 gcc 将使用一个内置函数并且根本不会发出对 sqrt 的调用,因为它将在编译时计算它。如果我们将代码更改为使用 sqrt(-9.0),它现在将发出( live example ):

call    sqrt

这将需要与 libm 链接,修复方法是将 -lm 添加到编译选项的末尾。

sqrt(-9) 的情况下,我们有一个域错误,如果转到 C99 草案标准部分 7.12.7.5 sqrt 函数 2 段说(强调我的):

The sqrt functions compute the nonnegative square root of x. A domain error occurs if the argument is less than zero.

如果我们回到 7.12.1 Treatment of error conditions 它说:

[...] On a domain error, the function returns an implementation-defined value; if the integer expression math_errhandling & MATH_ERRNO is nonzero, the integer expression errno acquires the value EDOM; if the integer expression math_errhandling & MATH_ERREXCEPT is nonzero, the ‘‘invalid’’ floating-point exception is raised.

因此将设置 errno 和/或将引发 float 异常,这似乎是 gcc 决定的情况优化效率不高。

关于c - sqrt 仅在参数为非负时定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20156285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com