Ошибка компоновки - gcc -lm - PullRequest
       48

Ошибка компоновки - gcc -lm

3 голосов
/ 22 января 2012

Ну, я думаю, что моя проблема немного интересна, и я хочу понять, что происходит в моем Ubuntu box.

Я скомпилировал и связал с gcc -lm -o useless useless.c следующий бесполезный фрагмент кода:

/*File useless.c*/
#include <stdio.h>
#include <math.h>
int main()
{
    int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
    return(0);
}

Пока все хорошо. Но когда я перехожу на это:

/*File useless.c*/
#include <stdio.h>
#include <math.h>
int main()
{
    int freq = 440;
    int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
    return(0);
}

И я пытаюсь скомпилировать, используя ту же командную строку, ответы gcc:

/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status

И останавливается. Что происходит? Почему я не могу так скомпилировать?

Я тоже безуспешно пробовал sudo ldconfig -v.

Заранее спасибо!

Лукас.

1 Ответ

12 голосов
/ 22 января 2012

Здесь происходят две разные вещи.

Для первого примера компилятор не генерирует вызов sin.Он видит, что аргумент является константным выражением, поэтому он заменяет вызов sin(...) результатом выражения, и математическая библиотека не нужна.Это будет работать так же хорошо без -lm.(Но вы не должны на это рассчитывать; не всегда очевидно, когда компилятор выполнит этот вид оптимизации, а когда - нет.)

(Если вы компилируете с

gcc -S useless.c

и взгляните на useless.s, список сгенерированного ассемблера, вы можете видеть, что нет вызова sin.)

Для второго примера вам нужен параметр -lm -но он должен находиться в конце командной строки или, по крайней мере, после нужного файла (useless.c):

gcc -o useless useless.c -lm

или

gcc useless.c -lm -o useless

Процессы компоновщикафайлы по порядку, отслеживая неразрешенные символы для каждого из них (sin, на которые ссылается useless.o), а затем разрешая их так, как они видят их определения.Если вы сначала поставите -lm, то при обработке математической библиотеки не будет неразрешенных символов;к тому времени, когда он видит вызов sin в useless.o, уже слишком поздно.

...