且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

log(10.0)可以编译,但log(0.0)不能使用未定义的引用?

更新时间:2023-01-25 14:17:44

gcc可以使用内置函数:

其中许多功能仅在某些情况下进行了优化;如果他们 在特定情况下未优化,则调用库函数 被发射.

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在使用内置函数时不需要链接到数学库,但由于log(0)

so therefore gcc will not need to link against the math library when using the builtin function but since log(0) is not defined it probably forcesgcc to evaluate it at run-time since it has a side effect.

如果我们查看 C99标准草案在第 4 段中的7.12.1 错误条件的处理部分中说(强调我的):

If we look at the draft C99 standard section 7.12.1 Treatment of error conditions in paragraph 4 it says (emphasis mine):

如果数学值的大小,则浮动结果会溢出 结果是有限的,但太大,以至于数学结果不能是 在没有异常舍入误差的情况下表示 指定的类型.如果浮动结果溢出并且默认舍入为 实际上,或者如果数学结果是从 有限参数(例如log(0.0)),则函数返回 宏HUGE_VAL,HUGE_VALF或HUGE_VALL的值取决于 返回类型,其符号与函数的正确值相同; 如果整数表达式math_errhandling& MATH_ERRNO不为零, 整数表达式errno获取值ERANGE; 表达式math_errhandling& MATH_ERREXCEPT为非零, 如果 数学结果是精确的无穷大和溢出" 否则会引发浮点异常.

A floating result overflows if the magnitude of the mathematical result is finite but so large that the mathematical result cannot be represented without extraordinary roundoff error in an object of the specified type. If a floating result overflows and default rounding is in effect, or if the mathematical result is an exact infinity from finite arguments (for example log(0.0)), then the function returns the value of the macro HUGE_VAL, HUGE_VALF, or HUGE_VALL according to the return type, with the same sign as the correct value of the function; if the integer expression math_errhandling & MATH_ERRNO is nonzero, the integer expression errno acquires the value ERANGE; if the integer expression math_errhandling & MATH_ERREXCEPT is nonzero, the ‘‘divide-by-zero’’ floating-point exception is raised if the mathematical result is an exact infinity and the ‘‘overflow’’ floating-point exception is raised otherwise.

在一个实时示例中,我们可以看到使用-S标志生成程序集,使用grep log过滤出对log的调用.

We can see from a live example using -S flag to generate assembly and grep log to filter out calls to log.

对于log(0.0),将生成以下指令( 实时查看 ):

In the case of log(0.0) the following instruction is generated (see it live):

call    log

,但在log(10.0)的情况下,不会生成call log指令,( 实时观看 ).

but in the case of log(10.0) no call log instruction is generated, (see it live).

我们通常可以通过使用gcc使用内置函数. rel ="nofollow noreferrer"> -fno-builtin标志,这可能是测试是否正在使用内置函数的更快方法.

We can usually prevent gcc from using builtin function by using the -fno-builtin flag which is probably a quicker way to test whether a builtin is being used.

请注意,-lm 需要在源文件之后进行搜索,例如(来自链接的答案),如果main.c需要数学库,则可以使用:

Note that -lm needs to go after the source file, for example (taken from linked answer) if main.c required the math library then you would use:

 gcc main.c -lm