2017-08-03 151 views
1

我碰到奇怪的問題,我需要通過-lm以鏗鏘它來編譯代碼:爲什麼clang需要-lm不像gcc?

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內聯函數調用,而鐺並不:

鐺:

$ nm -g test 
0000000000601048 B __bss_start 
       U [email protected]@GLIBC_2.2.5 
... 

GCC:

$ nm -g test 
0000000000601038 B __bss_start 
... 

我用的Kubuntu 16.04。鏗鏘3.8版和5.4.0版的gcc。

有沒有辦法使這些函數的鐺內聯調用?

+0

因爲他們是不同的編譯器,並有不同的庫實現? –

+0

@AjayBrahmakshatriya這不是一個圖書館問題。這是一個GCC擴展 - GCC提供了許多內置函數。 –

+0

@AndrewHenle由庫我不是指實際的lib(或所以)文件。我的意思是圖書館使用複數。一個通過內置函數實現它,另一個通過函數調用實現。儘管我使用了錯誤的措辭。 –

回答

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).

...

由於GCC提供conj()作爲一個內置的功能,你不GCC編譯時需要在libm.so(或libm.a)與-lm選項鍊接

+0

你知道如何讓這些函數內聯嗎?我深入地使用了clang,在我的情況下,gcc的表現優於許多因素,因爲它將內聯函數調用到這些函數中。 – Goovie

+0

@Goovie有關ng優化的一些信息,請參閱https://stackoverflow.com/questions/15548023/clang-optimization-levels。 –

+0

我修改了這個測試,在兩個編譯器上用「-O3 -flto」重新編譯,並且仍然沒有在clang中內聯這些函數,注意沒有優化過程能夠內聯這些函數,因爲clang沒有它們定義,顯然如果我想要內嵌這些函數,我必須自己編寫它們。 – Goovie