web-dev-qa-db-ja.com

「一部のmath.hのみ」関数への未定義の参照

私は奇妙な問題を抱えています。

数学ライブラリが私のメイクファイルに追加されました。

# include standard C library
LDFLAGS += -lc
# include standard math library
LDFLAGS += -lm

出力ファイル(.map)で、すべてが正しくリンクされていることがわかります。

LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/nof\libgcc.a
LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libc.a
LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libm.a

私がする時

z = pow((double) 2, (double) 3);

それはうまくいきます。しかし、次のような別の関数をテストすると、

double result = asin(x);

私は得るでしょう:

undefined reference to `asin'
collect2: ld returned 1 exit status

どうすればいいの? powasinの両方がmath.hで利用可能です。以下を参照してください。

/* Non reentrant ANSI C functions.  */

#ifndef _REENT_ONLY
#ifndef __math_6881
extern double acos _PARAMS((double));
extern double asin _PARAMS((double));
extern double atan2 _PARAMS((double, double));
extern double cosh _PARAMS((double));
extern double sinh _PARAMS((double));
extern double exp _PARAMS((double));
extern double ldexp _PARAMS((double, int));
extern double log _PARAMS((double));
extern double log10 _PARAMS((double));
extern double pow _PARAMS((double, double));
extern double sqrt _PARAMS((double));
extern double fmod _PARAMS((double, double));
#endif /* ! defined (__math_68881) */
#endif /* ! defined (_REENT_ONLY) */

一方がどのように機能し、もう一方がリンカーの問題を生成するのですか?-nm on libm.a次の結果が得られます:(膨大な出力で申し訳ありませんが、Wordのセクションのみをコピーしましたsin

lib_a-e_asin.o:
         U __adddf3
         U __divdf3
         U __gtdf2
00000000 T __ieee754_asin
         U __ieee754_sqrt
         U __muldf3
         U __subdf3
         U fabs

lib_a-e_j0.o:
         U __adddf3
         U __divdf3
         U __gtdf2
00000470 T __ieee754_j0
         U __ieee754_log
         U __ieee754_sqrt
000009b8 T __ieee754_y0
         U __ltdf2
         U __muldf3
         U __subdf3
         U cos
         U fabs
000000b0 r pR2
00000108 r pR3
00000058 r pR5
00000000 r pR8
000000e0 r pS2
00000138 r pS3
00000088 r pS5
00000030 r pS8
00000004 t pzero
00000220 r qR2
00000280 r qR3
000001c0 r qR5
00000160 r qR8
00000250 r qS2
000002b0 r qS3
000001f0 r qS5
00000190 r qS8
00000218 t qzero
         U sin

lib_a-e_j1.o:
         U __adddf3
         U __divdf3
         U __gtdf2
00000470 T __ieee754_j1
         U __ieee754_log
         U __ieee754_sqrt
00000950 T __ieee754_y1
         U __muldf3
         U __subdf3
         U cos
         U fabs
00000004 t pone
000000b0 r pr2
00000108 r pr3
00000058 r pr5
00000000 r pr8
000000e0 r ps2
00000138 r ps3
00000088 r ps5
00000030 r ps8
00000218 t qone
00000220 r qr2
00000280 r qr3
000001c0 r qr5
00000160 r qr8
00000250 r qs2
000002b0 r qs3
000001f0 r qs5
00000190 r qs8
         U sin

lib_a-e_jn.o:
         U __adddf3
         U __divdf3
         U __floatsidf
         U __gedf2
         U __gtdf2
         U __ieee754_j0
         U __ieee754_j1
00000434 T __ieee754_jn
         U __ieee754_log
         U __ieee754_sqrt
         U __ieee754_y0
         U __ieee754_y1
00000000 T __ieee754_yn
         U __ltdf2
         U __muldf3
         U __subdf3
         U cos
         U fabs
         U sin


lib_a-e_sinh.o:
         U __adddf3
         U __divdf3
         U __gtdf2
         U __ieee754_exp
00000000 T __ieee754_sinh
         U __muldf3
         U __subdf3
         U expm1
         U fabs


lib_a-ef_asin.o:
         U __addsf3
         U __divsf3
         U __gtsf2
00000000 T __ieee754_asinf
         U __ieee754_sqrtf
         U __mulsf3
         U __subsf3
         U fabsf


lib_a-ef_j0.o:
         U __addsf3
         U __divsf3
         U __gtsf2
0000035c T __ieee754_j0f
         U __ieee754_logf
         U __ieee754_sqrtf
000006cc T __ieee754_y0f
         U __ltsf2
         U __mulsf3
         U __subsf3
         U cosf
         U fabsf
00000058 r pR2
00000084 r pR3
0000002c r pR5
00000000 r pR8
00000070 r pS2
0000009c r pS3
00000044 r pS5
00000018 r pS8
00000004 t pzerof
00000110 r qR2
00000140 r qR3
000000e0 r qR5
000000b0 r qR8
00000128 r qS2
00000158 r qS3
000000f8 r qS5
000000c8 r qS8
000001a0 t qzerof
         U sinf

lib_a-ef_j1.o:
         U __addsf3
         U __divsf3
         U __gtsf2
0000031c T __ieee754_j1f
         U __ieee754_logf
         U __ieee754_sqrtf
0000062c T __ieee754_y1f
         U __mulsf3
         U __subsf3
         U cosf
         U fabsf
00000004 t ponef
00000058 r pr2
00000084 r pr3
0000002c r pr5
00000000 r pr8
00000070 r ps2
0000009c r ps3
00000044 r ps5
00000018 r ps8
000001a0 t qonef
000000b0 r qr2
000000e0 r qr8
000000c8 r qs2
000000f8 r qs8
         U sinf

lib_a-ef_sinh.o:
         U __addsf3
         U __divsf3
         U __gtsf2
         U __ieee754_expf
00000000 T __ieee754_sinhf
         U __mulsf3
         U __subsf3
         U expm1f
         U fabsf

lib_a-er_lgamma.o:
         U __adddf3
         U __divdf3
         U __eqdf2
         U __fixdfsi
         U __floatsidf
00000004 T __ieee754_lgamma_r
         U __ieee754_log
         U __kernel_cos
         U __kernel_sin
         U __ltdf2
         U __muldf3
         U __nedf2
         U __subdf3
         U fabs
         U floor


lib_a-erf_lgamma.o:
         U __addsf3
         U __divsf3
         U __eqsf2
         U __fixsfsi
         U __floatsisf
00000004 T __ieee754_lgammaf_r
         U __ieee754_logf
         U __kernel_cosf
         U __kernel_sinf
         U __ltsf2
         U __mulsf3
         U __nesf2
         U __subsf3
         U fabsf
         U floorf

lib_a-k_sin.o:
         U __adddf3
         U __fixdfsi
00000000 T __kernel_sin
         U __muldf3
         U __subdf3

lib_a-kf_sin.o:
         U __addsf3
         U __fixsfsi
00000000 T __kernel_sinf
         U __mulsf3
         U __subsf3

lib_a-s_asinh.o:
         U __adddf3
         U __divdf3
         U __gtdf2
         U __ieee754_log
         U __ieee754_sqrt
         U __muldf3
00000000 T asinh
         U fabs
         U log1p

lib_a-s_cos.o:
         U __ieee754_rem_pio2
         U __kernel_cos
         U __kernel_sin
         U __subdf3
00000000 T cos

lib_a-s_isinf.o:
00000000 T isinf

lib_a-s_isinfd.o:
00000000 T __isinfd

lib_a-s_sin.o:
         U __ieee754_rem_pio2
         U __kernel_cos
         U __kernel_sin
         U __subdf3
00000000 T sin

lib_a-sf_asinh.o:
         U __addsf3
         U __divsf3
         U __gtsf2
         U __ieee754_logf
         U __ieee754_sqrtf
         U __mulsf3
00000000 T asinhf
         U fabsf
         U log1pf

lib_a-sf_cos.o:
         U __ieee754_rem_pio2f
         U __kernel_cosf
         U __kernel_sinf
         U __subsf3
00000000 T cosf

lib_a-sf_isinf.o:
00000000 T isinff

lib_a-sf_isinff.o:
00000000 T __isinff

lib_a-sf_sin.o:
         U __ieee754_rem_pio2f
         U __kernel_cosf
         U __kernel_sinf
         U __subsf3
00000000 T sinf

lib_a-w_asin.o:
         U __errno
         U __fdlib_version
         U __gtdf2
         U __ieee754_asin
         U __isnand
00000004 T asin
         U fabs
         U matherr
         U nan

lib_a-w_sincos.o:
         U cos
         U sin
00000000 T sincos

lib_a-w_sinh.o:
         U __errno
         U __fdlib_version
         U __gtdf2
         U __ieee754_sinh
         U finite
         U matherr
00000004 T sinh

lib_a-wf_asin.o:
         U __errno
         U __extendsfdf2
         U __fdlib_version
         U __gtsf2
         U __ieee754_asinf
         U __truncdfsf2
00000004 T asinf
         U fabsf
         U isnanf
         U matherr
         U nan

lib_a-wf_sincos.o:
         U cosf
00000000 T sincosf
         U sinf

lib_a-wf_sinh.o:
         U __errno
         U __extendsfdf2
         U __fdlib_version
         U __gtsf2
         U __ieee754_sinhf
         U __truncdfsf2
         U finitef
         U matherr
00000004 T sinhf

EDIT1:もう少しテストしましたが、問題は次のとおりです(最初に述べたものではありません):

double aa;
double bb = 1.0;
double cc;
aa = sin(1.0);
cc = sin (bb);

ビルドしようとすると、最後の行に「undefined reference」が表示されます。つまり、定数を使用すると問題ありませんが、変数をsin関数に渡すと、リンクされません。他の数学関数の多くもテストしましたが、まったく同じリンカーの問題が発生します。変数を数学関数に渡すとすぐに、リンクできなくなります。何か案は?

11
theAlse

コンパイラが定数8.0に置き換えているため、リンカはpow((double) 2, (double) 3)について文句を言っていません。この動作に依存するべきではありません。代わりに、常に-lmオプションを適切に使用する必要があります。 (ところで、それはpow(2.0, 3.0)としてより明確に書かれています。

次のプログラムを検討してください。

#include <stdio.h>
#include <math.h>
int main(void) {
    double x = 0.1;
    printf("%g\n", pow(2.0, 3.0));
    printf("%g\n", asin(x));
    return 0;
}

を使用してシステム上でコンパイルおよびリンクする場合

gcc c.c -o c

私は得る:

/tmp/ccXx8ZRL.o: In function `main':
c.c:(.text+0x36): undefined reference to `asin'
collect2: ld returned 1 exit status

asinについては文句を言いますが、powについては文句を言わないことに注意してください。

pow呼び出しをpow(x, 3.0)に変更すると、次のようになります。

/tmp/ccOeSaBK.o: In function `main':
c.c:(.text+0x24): undefined reference to `pow'
c.c:(.text+0x52): undefined reference to `asin'
collect2: ld returned 1 exit status

通常、標準の数学ライブラリ関数を呼び出す場合は、ソースファイルの先頭に#include <math.h>を付ける必要があります(すでに持っていると思います)およびコンパイラに-lmオプションを渡す必要がありますそれを必要とするファイル。 (リンカはまだ解決されていない参照を追跡するため、最初にasinを参照するオブジェクトファイルを確認する必要があります。これにより、数学ライブラリを確認したときに解決できます。)

リンカはpow(2.0, 3.0)の呼び出しについて不平を言っていません。これは、gccが定数8.0に解決するのに十分賢いためです。コンパイルされたオブジェクトファイルにはpow関数の呼び出しがないため、リンカはそれを解決する必要はありません。 pow(2.0, 3.0)pow(x, 3.0)に変更すると、コンパイラーは結果がどうなるかわからないため、呼び出しを生成します。

9
Keith Thompson

-lm -lc -lgccのシーケンスは非常に重要な役割を果たします。このシーケンスだけが私のために働きます。

これらのコマンドはリンカーオプションに移動します!

8
ottelo

どこにでも<math.h>を含めていますか?

ライブラリ内の名前には接頭辞__ieee754_が付いていますが、リンカーが見つけられない名前はそうではないことに注意してください。

このコードをコンパイルするとどうなりますか?

#include <math.h>

int main(void)
{
    double d = pow(2, 3);
    double e = asin(1.0 / d);
    return (int)(e+1);
}

ファイルがmathtest.cの場合、次のコマンドでコンパイルします。

gcc -o mathtest mathtest.c -lm

(これがコンパイルに失敗した場合、mathtest.oで定義されているシンボルは何ですか?)


私は主な質問にコメントを追加しました:

どのプラットフォームを使用していますか?どのCコンパイラを使用していますか?クロスコンパイルしていますか?リンクを行うために実行されるコマンドラインは何ですか? (DOS/Windows C:パスとPowerPCアーキテクチャが表示されます。)型一般的な数学に使用している可能性はありますか?

あなたが与えるLOADパスを見ると、私はわかります:

LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libm.a

これは、次のように簡略化できると思います。

LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/powerpc-eabi/lib/nof\libm.a

私の興味をそそるその道の一部はnofの部分です。それは「浮動小数点なし」でしょうか?私が本当に興味をそそられる他の部分は、c:プレフィックスが付いたpowerpcの存在です。これは、WindowsプラットフォームでのPowerPCのクロスコンパイルのスマックです。そのようなことについて率直かつ明確にすることが重要です。私たちはあなたを賢明に助けることができるようにその種の情報を必要としています。

これは、テストしたlibm.aライブラリでしたか、それとも別のファイルで実験しましたか?

7

この問題を解決するには、「filename.c-lm」を使用できます。そして、ヘッダーファイルmath.hを使用することを忘れないでください

1
Mayank Kashyap