Undefined Reference to Math.h Functions: When Things Work Until They Don’t

So, here I am, minding my own business, trying to do math in C and a strange thing happened. I attempted to make a function that calculates the distance between two points:

double distance_formula(double x2, double y2, double x1, double y1)
{
return sqrt(pow((x2 - x1), 2) + pow((y2 - y1), 2));
}

… and then …

printf("The distance between 1,2 and -4,7 is: %f", distance_formula(1, 2, -4, 7));

This happens:

undefined reference to `sqrt'

More concerningly, if you change the distance_formula() function to…

double distance_formula(double x2, double y2, double x1, double y1)
{
return sqrt(20);
}

Everything works normally.

After poking around in the docs, verifying that sqrt() and pow() are in fact in math.h, I turn to the internet. It turns out that this is a somewhat common problem. As detailed in this Stack Overflow post:

“Including math.h brings in the declaration of the various functions and not their definition. The def is present in the math library libm.a. You need to link your program with this library so that the calls to functions like pow() are resolved.”

This is accomplished by appending -lm when you call gcc:

gcc -o line line.c -lm

Alternatively, if you’re using NetBeans:

  • Right click your project, click Properties
  • Click Linker
  • In the Additional Options field, enter -lm
  • Click OK
  • After this is done, everything works as expected. One question remains; why did sqrt(20) work? After some more research, I turned up this tidbit from the GCC 4.3 release notes:

    “The GCC middle-end has been integrated with the MPFR library. This allows GCC to evaluate and replace at compile-time calls to built-in math functions having constant arguments with their mathematically equivalent results. In making use of MPFR, GCC can generate correct results regardless of the math library implementation or floating point precision of the host platform. This also allows GCC to generate identical results regardless of whether one compiles in native or cross-compile configurations to a particular target. The following built-in functions take advantage of this new capability: acos, acosh, asin, asinh, atan2, atan, atanh, cbrt, cos, cosh, drem, erf, erfc, exp10, exp2, exp, expm1, fdim, fma, fmax, fmin, gamma_r, hypot, j0, j1, jn, lgamma_r, log10, log1p, log2, log, pow10, pow, remainder, remquo, sin, sincos, sinh, tan, tanh, tgamma, y0, y1 and yn. The float and long double variants of these functions (e.g. sinf and sinl) are also handled. The sqrt and cabs functions with constant arguments were already optimized in prior GCC releases. Now they also use MPFR.”

    Mystery solved, I guess. But consequences were never the same…

    2 responses to “Undefined Reference to Math.h Functions: When Things Work Until They Don’t”

    1. asdasd says :

      thanks sir, this post made my day as I was experiencing the same problem

      Like

    Trackbacks / Pingbacks

    1. Calling C++ Code from C | Doing My Programming... - June 25, 2013

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s

    %d bloggers like this: