Встроенные функции GCC - поведение 2003 против 2019 - PullRequest
3 голосов
/ 30 мая 2019

На странице 14 книги " Введение в GCC " автор Брайан Гоф , автор хочет показать ошибку компоновщика из-за отсутствия gcc сбиблиотека libm, в которой находится код функции sqrt:

$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function ‘main’:
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference to ‘sqrt’

Файл calc.c (где вызывается функция sqrt) таков:

#include <math.h>
#include <stdio.h>
int main (void)
{
    double x = sqrt (2.0);
    printf ("The square root of 2.0 is %f\n", x);
    return 0;
}

Эта книга написана в 2003 году. На моем текущем Ubuntu Linux 18 я не могу воспроизвести ошибку ссылки: она связывает и работает, печатая правильный результат:

$ ./calc
1.414214

Я нашел с ldd calcчто общая библиотека libm.so не вызывается во время выполнения.Конечно, здесь не задействована статическая библиотека libm.a.Так как же gcc работает с функцией sqrt?Я обнаружил, что в этом случае он использует встроенную функцию sqrt GCC .Его код вставляется в объектный файл calc.o во время компиляции.Так что нет ошибки «неопределенная ссылка».

Первый вопрос : это вся история или я что-то упустил?

Второй вопрос : почему это поведение относительно встроенных функций GCC так сильно изменилось в период с 2003 года (когда книга была написана) и сейчас?(Практически аннулирует весь пример, мне кажется)

Третий вопрос : почему автор приводит свои примеры (например, $ gcc -Wall calc.c -lm -o cal), подразумевая, что статическая библиотека libc.a будетиспользуется, когда на самом деле в Linux этот синтаксис вызывает динамическую библиотеку libm.so?Это специфично для Linux, а не для GNU GCC?Что я скучаю?

1 Ответ

3 голосов
/ 30 мая 2019

Я думаю, что это связано с оптимизацией постоянного значения. Современный GCC может вычислить точное значение sqrt (2.0). Если вы заставите его не использовать встроенные модули с -fno-builtin, он все равно не сможет установить связь. Кроме того, если вы немного измените код, чтобы аргумент sqrt() не был буквальным, он не сможет связать:

#include <math.h>
#include <stdio.h>

double t = 2.0;

int main (void)
{
    double x = sqrt (t);
    printf ("The square root of 2.0 is %f\n", x);
    return 0;
}

Это приводит к ошибке ссылки:

> gcc -o test test.c              
/usr/bin/ld: /tmp/ccLjHnQx.o: in function `main':
test.c:(.text+0x11): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

Что касается вашего третьего вопроса, -lm не подразумевает статическую библиотеку, AFAIK.

...