2012-01-22 2 views
2

Ну, я думаю, что моя проблема немного интересна, и я хочу понять, что происходит в моем поле Ubuntu.Ошибка ссылки - gcc -lm

Я скомпилировал и связанный с 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 без успеха.

Спасибо заранее!

Lucas.

+0

'int main()' должно быть 'int main (void)'. Скобки в инструкции 'return' не нужны; вы можете просто написать 'return 0;'. –

ответ

11

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

Для первого примера компилятор не вызывает вызов 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, уже слишком поздно.

+1

Я собирался опубликовать то же самое, но не мог понять, почему первое удалось ('sin()' также используется). – hmjd

+0

@hmjd: Ах, я читал это слишком быстро. См. Мой обновленный ответ. –

+0

+1, очень полезно. – hmjd

Смежные вопросы