неопределенная ссылка на "только некоторые math.h" функции - PullRequest
10 голосов
/ 30 июня 2011

У меня странная проблема.

В мой make-файл добавлены математические библиотеки.

# 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

Как это может быть? pow и asin доступны в 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 на libm.a , я получу следующий результат: (извините за огромный вывод, я только скопировалразделы со словом 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);

Когда я пытаюсь построить, происходит то, что я получаю ' неопределенную ссылку ' в последней строке, что означает, что когда яиспользовать константы - это хорошо, но когда я передаю переменные в функции sin, они не будут связываться.Я также протестировал многие другие математические функции и получу точно такую ​​же проблему с компоновщиком.Как только я передаю переменную в математическую функцию, я больше не могу связывать.есть идеи?

Ответы [ 4 ]

8 голосов
/ 27 сентября 2012

Последовательность для -lm -lc -lgcc играет очень важную роль. Только эта последовательность работает для меня.

Эти команды идут в Опции компоновщика!

7 голосов
/ 11 июля 2015

Компоновщик не жалуется на pow((double) 2, (double) 3), потому что компилятор заменяет его константой 8.0. Вы не должны зависеть от этого поведения; вместо этого вы всегда должны правильно использовать опцию -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> вверху исходного файла (я полагаю, у вас это уже есть) и вам нужно передать * Опция 1028 * для компилятора после файла, который нуждается в нем. (Компоновщик отслеживает ссылки, которые еще не были разрешены, поэтому он должен сначала увидеть объектный файл, который ссылается на asin, поэтому он может разрешить его, когда видит библиотеку математики.)

Компоновщик не жалуется на вызов pow(2.0, 3.0), потому что gcc достаточно умен, чтобы разрешить его до константы 8.0. В скомпилированном объектном файле нет вызова функции pow, поэтому компоновщик не должен ее разрешать. Если я изменю pow(2.0, 3.0) на pow(x, 3.0), компилятор не знает, каким будет результат, поэтому он генерирует вызов.

7 голосов
/ 30 июня 2011

Вы включаете <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 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часть;это может быть «без плавающей запятой»?Другая часть, которая действительно меня интригует, - это наличие powerpc с префиксом c:;это попахивает кросс-компиляцией для PowerPC на платформе Windows.Важно быть откровенным и откровенным о таких вещах;нам нужна такая информация, чтобы помочь вам разумно.

Была ли это проверенная вами библиотека libm.a или вы экспериментировали с другим файлом?

1 голос
/ 27 сентября 2016

Вы можете использовать «filename.c -lm» для решения этой проблемы.И, пожалуйста, не забудьте использовать заголовочный файл math.h

...