为什么 clang 需要 -lm 不像 gcc?
Why does clang require -lm unlike gcc?
我 运行 遇到了一个奇怪的问题,我需要将 -lm 传递给 clang 以便它编译代码:
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;
}
具体来说,存在链接器错误:
/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)
我注意到的一件重要事情是,在这种情况下,gcc 能够轻松胜过 clang,因为 gcc 内联函数调用而 clang 没有:
叮当声:
$ nm -g test
0000000000601048 B __bss_start
U conj@@GLIBC_2.2.5
...
gcc:
$ nm -g test
0000000000601038 B __bss_start
...
我使用的是 kubuntu 16.04。 Clang 3.8 版本和 5.4.0 gcc 版本。
有没有办法对这些函数进行 clang 内联调用?
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).
...
由于 GCC 提供 conj()
作为内置函数,因此您不需要 libm.so
(或 libm.a
)中的 link 和 -lm
使用 GCC 编译时的选项
我 运行 遇到了一个奇怪的问题,我需要将 -lm 传递给 clang 以便它编译代码:
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;
}
具体来说,存在链接器错误:
/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)
我注意到的一件重要事情是,在这种情况下,gcc 能够轻松胜过 clang,因为 gcc 内联函数调用而 clang 没有:
叮当声:
$ nm -g test
0000000000601048 B __bss_start
U conj@@GLIBC_2.2.5
...
gcc:
$ nm -g test
0000000000601038 B __bss_start
...
我使用的是 kubuntu 16.04。 Clang 3.8 版本和 5.4.0 gcc 版本。
有没有办法对这些函数进行 clang 内联调用?
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).
...
由于 GCC 提供 conj()
作为内置函数,因此您不需要 libm.so
(或 libm.a
)中的 link 和 -lm
使用 GCC 编译时的选项