Вопрос по c – Почему вы должны связать математическую библиотеку в C?

222

Если я включу<stdlib.h> или же<stdio.h> в программе на Си мне не нужно связывать их при компиляции, но я должен ссылаться на<math.h>, с помощью-lm с gcc, например:

gcc test.c -o test -lm

Что является причиной этого? Почему я должен явно связать математическую библиотеку, а не другие библиотеки?

Ваш Ответ

9   ответов
3

что это произвольно. Вы должны нарисовать линию где-нибудь (какие библиотеки по умолчанию, а какие нужно указать).

Это дает вам возможность заменить его другим, имеющим те же функции, но я не думаю, что это очень распространено.

РЕДАКТИРОВАТЬ: (из моих собственных комментариев): , что gcc делает это для обеспечения обратной совместимости с оригинальным cc. Я предполагаю, почему cc делает это из-за времени сборки - cc был написан для машин с гораздо меньшей мощностью, чем у нас сейчас. Во многих программах отсутствует математика с плавающей запятой, и они, вероятно, взяли каждую библиотеку, которая обычно не использовалась, по умолчанию. Я предполагаю, что движущей силой было время сборки ОС UNIX и соответствующие инструменты.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

guess что это способ заставить приложения, которые вообще не используют его, работать немного лучше. Вот мои мысли по этому поводу.

Операционные системы x86 (и я полагаю, другие) должны хранить состояние FPU при переключении контекста. Тем не менее, большинство операционных систем пытаются сохранить / восстановить это состояние только после того, как приложение попытается использовать FPU в первый раз.

В дополнение к этому, вероятно, есть некоторый базовый код в математической библиотеке, который установит FPU в нормальное базовое состояние при загрузке библиотеки.

Таким образом, если вы вообще не будете ссылаться в каком-либо математическом коде, ничего этого не произойдет, поэтому ОС вообще не нужно сохранять / восстанавливать любое состояние FPU, что делает переключение контекста немного более эффективным.

Просто предположение, хотя.

EDIT: в ответ на некоторые комментарии та же базовая предпосылка все еще применяется к случаям без FPU (предпосылка состоит в том, чтобы заставить приложения, которые не используют libm, работать немного лучше).

Например, если есть программный FPU, который был похож на ранние времена C. Тогда наличие раздельного libm могло бы предотвратить ненужное связывание большого количества (и медленного, если оно использовалось) кода.

Кроме того, если доступно только статическое связывание, то применяется аналогичный аргумент, который ограничивает размеры исполняемого файла и время компиляции.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

t have to link those but I have to link when I compile:

stdlib.h, stdio.h являются заголовочными файлами. Вы включаете их для вашего удобства. Они только прогнозируют, какие символы станут доступными, если вы укажете ссылку в соответствующей библиотеке. Реализации находятся в файлах библиотеки, где функции действительно живут.

В том числеmath.h это только первый шаг к получению доступа ко всем математическим функциям.

Кроме того, вам не нужно связываться сlibm если вы не используете его функции, даже если вы делаете#include <math.h> это только информационный шаг для вас, для компилятора о символах.

stdlib.h, stdio.h обратитесь к функциям, доступным вlibc, который всегда связан с тем, что пользователю не нужно делать это самому.

5

библиотека C libc по умолчанию связана, и эта библиотека содержит реализации stdlib.h, stdio.h и нескольких других стандартных заголовочных файлов. Просто добавить к этому, в соответствии с & quot;Введение в GCC& Quot; команда компоновщика для базового "Hello World" Программа на C выглядит так:

ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/libgcc-lib /i686/3.3.1/crtbegin.o
-L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc 
-lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.o

Обратите внимание на вариант-lc в третьей строке, которая связывает библиотеку C.

66

что C является старым языком, а FPU - явление относительно недавнее. Я впервые увидел C на 8-битных процессорах, где было много работы, чтобы выполнить даже 32-битную целочисленную арифметику. Многие из этих реализаций даже неhave доступна математическая библиотека с плавающей точкой!

Даже на первых 68000 машин (Mac, Atari ST, Amiga) сопроцессоры с плавающей запятой часто были дорогими дополнениями.

Чтобы выполнить всю эту математику с плавающей запятой, вам нужна довольно большая библиотека. И математика собиралась быть медленной. Таким образом, вы редко использовали поплавки. Вы пытались сделать все с целыми или масштабированными целыми числами. Когда вам приходилось включать математику, вы стиснули зубы. Зачастую вы пишете свои собственные аппроксимации и таблицы поиска, чтобы избежать этого.

Компромиссы существовали в течение длительного времени. Иногда встречались конкурирующие математические пакеты, называемые «fastmath». или такой. Какое лучшее решение для математики? Действительно точный, но медленный материал? Неточно, но быстро? Большие таблицы для тригонометрических функций? До тех пор, пока сопроцессоры не оказались в компьютере, большинство реализаций стало очевидным. Я полагаю, что где-то прямо сейчас есть какой-то программист, работающий над встроенным чипом и пытающийся решить, стоит ли вводить математическую библиотеку для решения некоторой математической задачи.

Вот почему математика не былаstandard, Многие или, может быть, большинство программ не используют один float. Если бы FPU всегда были рядом, а поплавки и парные удары всегда были дешевы в эксплуатации, без сомнения, был бы «stdmath».

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededlibmError: User Rate Limit ExceededstandardError: User Rate Limit Exceededde factoError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

с которой по умолчанию будет ссылаться gcc.

Реализации математической функции находятся в отдельном файле libm, который не связан по умолчанию, поэтому вы должны указать его -lm. Кстати, между этими заголовочными файлами и библиотеками нет никакой связи.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededwhy
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
26

Вот:

So if your program is using math functions and including math.h, then you need to explicitly link the math library by passing the -lm flag. The reason for this particular separation is that mathematicians are very picky about the way their math is being computed and they may want to use their own implementation of the math functions instead of the standard implementation. If the math functions were lumped into libc.a it wouldn't be possible to do that.

[Редактировать]

Хотя я не уверен, что согласен с этим. Если у вас есть библиотека, которая обеспечивает, скажем,sqrt(), и вы передаете его перед стандартной библиотекой, линкер Unix возьмет вашу версию, верно?

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededsqrtError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded-lmError: User Rate Limit Exceeded
211

stdlib.h а такжеstdio.h есть реализации вlibc.so (или жеlibc.a для статической компоновки), которая по умолчанию связана с вашим исполняемым файлом (как будто-lc были указаны). GCC можно поручить избегать этой автоматической связи с-nostdlib или же-nodefaultlibs опции.

Математические функции вmath.h есть реализации вlibm.so (или жеlibm.a для статического связывания) иlibm по умолчанию не связан Есть исторические причины для этогоlibm/libc Расколотый, ни один из них не очень убедительный.

Интересно, что C ++ Runtimelibstdc++ требуетlibm, так что если вы компилируете программу на C ++ с GCC (g++), вы автоматически получитеlibm связаны в.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededmostError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
4

Введение в GCC - Связь с внешними библиотеками, Если библиотека является членом стандартных библиотек (например, stdio), вам не нужно указывать компилятору (на самом деле компоновщику), чтобы связать их.

РЕДАКТИРОВАТЬ: после прочтения некоторых других ответов и комментариев, я думаю,ссылка на libc.a и ссылка на libm, на которую она ссылается, может многое сказать о том, почему они разделены.

Note that many of the functions in 'libm.a' (the math library) are defined in 'math.h' but are not present in libc.a. Some are, which may get confusing, but the rule of thumb is this--the C library contains those functions that ANSI dictates must exist, so that you don't need the -lm if you only use ANSI functions. In contrast, `libm.a' contains more functions and supports additional functionality such as the matherr call-back and compliance to several alternative standards of behavior in case of FP errors. See section libm, for more details.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededsqrtError: User Rate Limit Exceeded-lmError: User Rate Limit Exceeded

Похожие вопросы