1

I've run into weird issue where I need to pass -lm to clang in order for it to compile the code:

gcc test.c -o test       #works
clang test.c -o test     #doesn't work
clang -lm test.c -o test #works


#include <stdio.h>
#include <complex.h>

int main() {
    double complex z = 1.0 + 3.0 * I;
    double complex conjugate = conj(z);
    printf("The conjugate of Z is = %.2f %+.2fi\n", creal(conjugate), cimag(conjugate));
    return 0;
}

Specifically, there is linker error:

/tmp/test-561678.o: In function `main':
test.c:(.text+0x4a): undefined reference to `conj'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

One important thing I noticed is that in this case gcc is able to outperform clang easily, because gcc inlines function calls whereas clang doesn't:

clang:

$ nm -g test
0000000000601048 B __bss_start
                 U conj@@GLIBC_2.2.5
...

gcc:

$ nm -g test
0000000000601038 B __bss_start
...

I use kubuntu 16.04. Clang 3.8 version, and 5.4.0 gcc version.

Is there a way to make clang inline calls to these functions ?

Goovie
  • 159
  • 1
  • 11
  • Because they are different compilers and have different implementations of the libraries? – Ajay Brahmakshatriya Aug 03 '17 at 13:08
  • @AjayBrahmakshatriya It's not a library issue at all. It's a GCC extension - GCC provides many built-in functions. – Andrew Henle Aug 03 '17 at 13:10
  • @AndrewHenle by library I didn't mean actual lib (or so) files. I meant the library to use complex numbers. One implements it through builtins, other does it using function calls. I used wrong wordings though. – Ajay Brahmakshatriya Aug 03 '17 at 13:13

1 Answers1

4

GCC provides numerous built-in functions:

6.59 Other Built-in Functions Provided by GCC

GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and are not documented here because they may change from time to time; we do not recommend general use of these functions.

The remaining functions are provided for optimization purposes.

...

The ISO C99 functions _Exit, acoshf, acoshl, acosh, asinhf, asinhl, asinh, atanhf, atanhl, atanh, cabsf, cabsl, cabs, cacosf, cacoshf, cacoshl, cacosh, cacosl, cacos, cargf, cargl, carg, casinf, casinhf, casinhl, casinh, casinl, casin, catanf, catanhf, catanhl, catanh, catanl, catan, cbrtf, cbrtl, cbrt, ccosf, ccoshf, ccoshl, ccosh, ccosl, ccos, cexpf, cexpl, cexp, cimagf, cimagl, cimag, clogf, clogl, clog, conjf, conjl, conj, copysignf, copysignl, copysign, cpowf, cpowl, cpow, cprojf, cprojl, cproj, crealf, creall, creal, csinf, csinhf, csinhl, csinh, csinl, csin, csqrtf, csqrtl, csqrt, ctanf, ctanhf, ctanhl, ctanh, ctanl, ctan, erfcf, erfcl, erfc, erff, erfl, erf, exp2f, exp2l, exp2, expm1f, expm1l, expm1, fdimf, fdiml, fdim, fmaf, fmal, fmaxf, fmaxl, fmax, fma, fminf, fminl, fmin, hypotf, hypotl, hypot, ilogbf, ilogbl, ilogb, imaxabs, isblank, iswblank, lgammaf, lgammal, lgamma, llabs, llrintf, llrintl, llrint, llroundf, llroundl, llround, log1pf, log1pl, log1p, log2f, log2l, log2, logbf, logbl, logb, lrintf, lrintl, lrint, lroundf, lroundl, lround, nearbyintf, nearbyintl, nearbyint, nextafterf, nextafterl, nextafter, nexttowardf, nexttowardl, nexttoward, remainderf, remainderl, remainder, remquof, remquol, remquo, rintf, rintl, rint, roundf, roundl, round, scalblnf, scalblnl, scalbln, scalbnf, scalbnl, scalbn, snprintf, tgammaf, tgammal, tgamma, truncf, truncl, trunc, vfscanf, vscanf, vsnprintf and vsscanf are handled as built-in functions except in strict ISO C90 mode (-ansi or -std=c90).

...

Since GCC provides conj() as a built-in function, you don't need to link in libm.so (or libm.a) with the -lm option when compiling with GCC

Community
  • 1
  • 1
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • 1
    Do you know how to make these functions get inlined? I use clang intensively and in my case gcc outperforms clang by many factors because it inlines calls to these functiosn. – Goovie Aug 03 '17 at 13:30
  • @Goovie See https://stackoverflow.com/questions/15548023/clang-optimization-levels for some information regarding clang optimization. – Andrew Henle Aug 03 '17 at 13:34
  • I've modified this test, recompiled with "-O3 -flto" on both compilers, and still don't get these functions inlined in clang, note that no optimization pass is able to inline these functions as clang doesn't have their definitions, apparently if I wanted to have these functions inlined I have to write them by myself. – Goovie Aug 03 '17 at 14:03
  • @Goovie I'm not familiar enough with clang to know why it's not inlining the `conj()` function in your example. I'd recommend another question. – Andrew Henle Aug 03 '17 at 15:12
  • 1
    Well... the answer to clang not being able to inline these functions is obvious to me now. It just doesn't have it's definitions. "-lm" links with dynamic library, and it would be stupid to perform inlining of dynamically called function (we wouldn't be able to do dynamic dispatch then). If you call gcc with "-fno-builtins" it's going to get all of these functions called dynamically as well. – Goovie Aug 06 '17 at 02:01