Странное числовое поведение gcc Linker
У меня проблема с простым кодом C следующим образом:
#include <math.h>
#include <stdio.h>
int main () {
printf ("%f\n", exp(1));
}
Замена 1
номерами, меньшими 710
, приводит к успешной компиляции с ожидаемым эффектом, но для чисел, превышающих это, я получаю ошибку компоновщика всех вещей:
/tmp/ccqVnsno.o: In function `main':
test.c:(.text+0x1c): undefined reference to `exp'
collect2: error: ld returned 1 exit status
Я тестировал это для чисел ниже 1000 со следующим bash script:
for i in {0..1000}; do
sed -i -r "s:[0-9]+:${i}:" test.c
gcc -o test test.c
./test
done
Приведение операторов printf
в цикл for с помощью exp
индексной переменной приводит к той же ошибке привязки, независимо от верхней границы.
Что здесь происходит? Является ли компилятор признанием 710 как своего рода пределом для long double
? Тогда почему компоновщик поймал ошибку? Извините за доверчивость, я новичок в C.
Ответы
Ответ 1
Я предполагаю, что для меньших чисел компилятор GCC оптимизирует вызов exp
во что-то другое, но для больших номеров ему нужен стандартный реализация, которая находится в математической библиотеке. И математическая библиотека должна быть явно связана с.
Вы связываетесь с математической библиотекой, добавляя опцию -lm
при связывании. Это вариант -l
(нижний регистр L), который сообщает компоновщику ссылку на библиотеку, и m
для библиотеки m.
Что касается возможных оптимизаций функции exp
, вы можете вызвать ее с небольшим числом, а затем использовать дизассемблер для проверки сгенерированного код.