log(10.0) can compile but log(0.0) cannot with undefined reference?

gcc can use builtin functions in many cases, their documentation says:

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.

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.

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

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.

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

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

call    log

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

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.

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 

Leave a Comment