Почему вам нужно связывать математическую библиотеку на C?

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

gcc test.c -o test -lm

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


person Nope    schedule 23.06.2009    source источник


Ответы (14)


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

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

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

person ephemient    schedule 23.06.2009
comment
Хорошо, это становится вопросом дизайна библиотеки - почему библиотеки разделены таким образом? - person ; 23.06.2009
comment
Готов поспорить, чтобы оптимизировать время сборки самой UNIX (и сопутствующего ей набора инструментов). В то время это было, наверное, самое сложное, что создавалось на C. - person Lou Franco; 23.06.2009
comment
что-нибудь делать с эмуляцией fpu? но для Linux возможная эмуляция находится в ядре, а не в libm .. верно? - person Joakim Elofsson; 23.06.2009
comment
Я читал это потому, что хакеры Unix обычно писали свои собственные математические функции. - person Bastien Léonard; 23.06.2009
comment
Это не имеет ничего общего с Linux, поскольку это было распространено задолго до Linux. Я подозреваю, что это как-то связано с попыткой минимизировать размер исполняемого файла, поскольку существует множество программ, которым не нужны математические функции. - person David Thornley; 23.06.2009
comment
В древних системах, если бы математические функции содержались в libc, компиляция всех программ была бы медленнее, выходные исполняемые файлы были бы больше, а время выполнения потребовало бы больше памяти, что не принесет пользы большинству программ, которые не вообще использовать эти математические функции. В наши дни у нас есть хорошая поддержка разделяемых библиотек, и даже при статической компоновке стандартные библиотеки настроены так, что неиспользуемый код можно отбросить, так что ни одна из этих причин больше не является веской. - person ephemient; 23.06.2009
comment
@ephemient: У вас есть ссылка для получения соответствующей информации об этом? - person Eliseo Ocampos; 23.06.2009
comment
@ephemient: этот последний комментарий - веская причина и, скорее всего, правда :-P. Отредактируйте это в своем сообщении, и вы получите мой +1. - person Evan Teran; 23.06.2009
comment
@ephemient Даже в старые времена связывание с библиотекой не втягивало все содержимое библиотеки в исполняемый файл. Линкеры, хотя технология часто игнорируется, исторически были довольно эффективными. - person ; 23.06.2009
comment
@ephemient Кроме того, общие библиотеки существуют дольше, чем вы думаете. Они были изобретены в 1950-х, а не в 1980-х. - person ; 23.06.2009
comment
Это зависит от того, как настроены объекты в архиве библиотеки, и поскольку многие из этих систем появились раньше меня, я не могу точно заявить о них. Однако имеет смысл, что создатели системы заранее проделали бы дополнительную работу, чтобы разделить объекты библиотеки, чтобы сделать это возможным. - person ephemient; 23.06.2009
comment
Общие библиотеки существуют всегда, но, насколько мне известно, многие системы все еще использовали статически связанные библиотеки даже для libc. Stratus VOS, например, все еще развертывается и поддерживается, и в большинстве развертываний вообще нет общих библиотек ... - person ephemient; 23.06.2009
comment
Я полагаю, в конце концов, то, на что мы смотрим, является не чем иным, как консерватизмом GCC: он всегда так работал. Я только хочу, чтобы они применили те же рассуждения к своим расширениям компилятора. - person ; 23.06.2009
comment
Я не могу реально представить, что что-то сломается, если libm будет объединена с libc (а libm превратится в пустую заглушку, поэтому -lm не дает сбоев). Ну что ж. - person ephemient; 23.06.2009
comment
@Niel Используйте -std = c99 или что-то еще. - person Jed; 08.11.2009
comment
Почему в llvm gcc я могу опустить -lm? - person bot47; 14.12.2011
comment
Привет, мне любопытно, почему gcc -std = c89 нужен флаг -lm, clang -std = c89, c99, c11 также нужен этот флаг, но gcc -std = c99, c11 нет. GCC 4.8.1, clang 3.5 svn транк. - person sasha.sochka; 14.01.2014
comment
Почему вы говорите, что причины неубедительны. Имеет смысл отделить математические функции от стандартной библиотеки. - person doc; 09.12.2019

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

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

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

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

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

person Nosredna    schedule 23.06.2009
comment
Хех, я использую аппроксимации Паде для (1 + x) ^ y в Java на настольном ПК. Log, exp и pow по-прежнему медленные. - person quant_dev; 24.06.2009
comment
Хорошая точка зрения. И я видел приближения для sin () в аудио плагинах. - person Nosredna; 24.06.2009
comment
Это объясняет, почему libm не связан по умолчанию, но математика была стандартной из C89, а до этого K&R де-факто стандартизировал ее, поэтому ваше замечание stdmath не имеет смысл. - person Fred Foo; 14.11.2011
comment
@FredFoo Были стандартизированы типы и интерфейсы, но не реализации. Я думаю, что «Носредна» имеет в виду стандартную математическую библиотеку. - person Tim Bird; 22.01.2020

Из-за нелепой исторической практики, которую никто не хочет исправлять. Объединение всех функций, требуемых C и POSIX, в один файл библиотеки не только позволит избежать повторения этого вопроса снова и снова, но также сэкономит значительное количество времени и памяти при динамической компоновке, поскольку каждый связанный файл .so требует файловой системы операции по поиску и поиску, а также несколько страниц для его статических переменных, перемещений и т. д.

Реализация, в которой все функции находятся в одной библиотеке, а параметры -lm, -lpthread, -lrt и т. Д. Не работают (или связаны с пустыми .a файлами), полностью совместима с POSIX и, безусловно, предпочтительна.

Примечание: я говорю о POSIX, потому что сам C ничего не определяет о том, как вызывается компилятор. Таким образом, вы можете просто рассматривать gcc -std=c99 -lm как зависящий от реализации способ, которым компилятор должен быть вызван для согласованного поведения.

person R.. GitHub STOP HELPING ICE    schedule 05.01.2011
comment
+1 за указание на то, что POSIX не требует наличия разделенных библиотек libm, libc и librt. Например, в Mac OS все находится в одной libSystem (которая также включает libdbm, libdl, libgcc_s, libinfo, libm, libpoll, libproc и librpcsvc). - person F'x; 05.01.2011
comment
–1 для размышлений о влиянии поиска в библиотеке на производительность без подкрепления ссылками или числами. Профиль. Не спекулируйте - person F'x; 05.01.2011
comment
Это не домыслы. У меня нет опубликованных работ, но все измерения я провел сам, и разница огромна. Просто используйте strace с одним из параметров синхронизации, чтобы посмотреть, сколько времени при запуске тратится на динамическое связывание, или сравните запуск ./configure в системе, в которой все стандартные утилиты связаны статически, с одной, в которой они связаны динамически. Даже основные разработчики настольных приложений и системные интеграторы знают о стоимости динамического связывания; вот почему существуют такие вещи, как prelink. Я уверен, что вы можете найти тесты в некоторых из этих статей. - person R.. GitHub STOP HELPING ICE; 06.01.2011
comment
Обратите внимание, что POSIX действительно требует принятия -lm, а приложения, использующие математические интерфейсы, должны использовать -lm, но это может быть внутренняя опция, обрабатываемая (или даже игнорируемая) командой компилятора, а не фактический файл библиотеки. . Или это может быть просто пустой .a файл, если интерфейсы находятся в основной libc. - person R.. GitHub STOP HELPING ICE; 06.01.2011
comment
@FX: Не знаю, почему я забыл упомянуть об этом раньше: strace -tt легко покажет вам время, потраченное на динамическое связывание. Это некрасиво. А в Linux проверка /proc/sys/smaps покажет вам накладные расходы памяти дополнительных библиотек. - person R.. GitHub STOP HELPING ICE; 02.04.2011
comment
-1 за нелепую историческую практику. Это оценочно и ИМХО неточно. См. Ответ @Nosredna, чтобы узнать, почему эта практика вовсе не была нелепой с исторической точки зрения. - person Tim Bird; 22.01.2020
comment
@TimBird: Большая часть этого ответа, кажется, предполагает неправильное предположение, что связывание библиотеки извлекает из нее все, а не только функции (с детализацией единицы перевода, но исторически они были правильно разделены на отдельные функции), которые вы используете. - person R.. GitHub STOP HELPING ICE; 23.01.2020
comment
@ R..GitHubSTOPHELPINGICE: Нет. Большая часть этого ответа связана со скоростью и точностью, с некоторым упоминанием места. В свое время я много программировал на системах без FPU (8086, 286, начало 386), и этот комментарий является точным описанием компромиссов для той эпохи (только некоторые из них были примерно размера). - person Tim Bird; 24.01.2020
comment
@TimBird: наличие математической части стандартной библиотеки, доступной по умолчанию без записи -lm, не имеет к этому никакого отношения. Это не мешает не использовать его или написать свою собственную, быструю, но неточную версию. Все эти соображения были реальными, но они не имели отношения к -lm. - person R.. GitHub STOP HELPING ICE; 25.01.2020
comment
Со своей стороны, я скажу плюс 1 за нелепую историческую практику, потому что это именно то, что есть. Причины, по которым математическая библиотека рассматривалась отдельно и специально перестали быть актуальными в конце 80-х или начале 90-х годов. Сегодня единственная цель, которой служит отдельное устройство, - это расстраивать новичков. Меня сбивает с толку, что это различие до сих пор упорно сохраняется. - person Steve Summit; 15.06.2021

Поскольку time() и некоторые другие функции builtin определены в самой библиотеке C (libc), а GCC всегда ссылается на libc , если вы не используете параметр компиляции -ffreestanding. Однако математические функции находятся в libm, который неявно связан с gcc.

person ismail    schedule 05.01.2011
comment
В LLVM gcc мне не нужно добавлять -lm. Почему это? - person bot47; 14.12.2011

Объяснение приводится здесь:

Поэтому, если ваша программа использует математические функции и включает math.h, вам необходимо явно связать математическую библиотеку, передав флаг -lm. Причина этого особого разделения заключается в том, что математики очень разборчивы в том, как вычисляется их математика, и они могут захотеть использовать свою собственную реализацию математических функций вместо стандартной реализации. Если бы математические функции были объединены в libc.a, это было бы невозможно.

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

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

person Bastien Léonard    schedule 23.06.2009
comment
Я не думаю, что есть гарантия, что это произойдет; вместо этого вы можете столкнуться с конфликтом символов. Вероятно, это будет зависеть от компоновщика и макета библиотеки. Я все еще считаю эту причину слабой; если вы создаете пользовательскую функцию sqrt, вам действительно не следует давать ей то же имя, что и стандартная функция sqrt, даже если она делает то же самое ... - person ephemient; 24.06.2009
comment
Действительно, создание вашей собственной функции (нестатической) с именем sqrt приводит к программе с неопределенным поведением. - person R.. GitHub STOP HELPING ICE; 02.08.2010
comment
@Bastien Хорошая находка. И, переходя к вашей точке зрения, что вы имеете в виду под стандартной библиотекой? Я подумал, что стандартная библиотека подключается по умолчанию, и ее не требуется связывать с помощью параметров командной строки. Таким образом, стандартная библиотека будет первым выбором для компоновщика, и нельзя размещать собственную реализацию перед стандартной библиотекой. - person Rocky Inde; 05.03.2015
comment
@RockyInde: посмотрите на мой ответ, я думаю, что на самом деле имел в виду «до появления стандартной математической библиотеки». Но я думаю, что есть варианты компилятора, чтобы не связывать стандартную библиотеку C, что позволило бы вам передать вашу. - person Bastien Léonard; 05.03.2015
comment
@ BastienLéonard Я использую gcc версии 7.2, которая -lm совершенно не обязательна. Любые идеи - person Donghua Liu; 22.06.2018
comment
есть гарантия, что это произойдет, если вы не используете какой-либо дистрибутив с конца 2005 года. - person clockw0rk; 16.12.2020

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

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

Обратите внимание, что многие функции в libm.a (математическая библиотека) определены в math.h, но отсутствуют в libc.a. Некоторые из них могут сбивать с толку, но практическое правило таково: библиотека C содержит те функции, которые, согласно требованиям ANSI, должны существовать, поэтому вам не понадобится -lm, если вы используете только функции ANSI. Напротив, libm.a содержит больше функций и поддерживает дополнительные функции, такие как обратный вызов matherr и соответствие нескольким альтернативным стандартам поведения в случае ошибок FP. Смотрите раздел libm для более подробной информации.

person Bill the Lizard    schedule 23.06.2009
comment
Это не отвечает на вопрос, почему вам нужно отдельно связывать библиотеки совпадений. Очевидно, вы хотите связать библиотеки OpenGL отдельно, но, возможно, математические библиотеки в целом полезны. - person David Thornley; 23.06.2009
comment
@ Дэвид: Верно. Из вопроса мне не было ясно, что именно об этом спрашивал ОП. Я редактировал свой ответ, пока вы комментировали. - person Bill the Lizard; 23.06.2009
comment
Я знаю причину, по которой я скомпилировал программу, использующую функцию sqrt, и она работает без включения библиотеки через -lm. Спасибо! - person L_K; 01.06.2017

Как сказал ephemient, библиотека C libc связана по умолчанию, и эта библиотека содержит реализации stdlib.h, stdio.h и несколько других стандартных файлов заголовков. Чтобы добавить к нему, согласно "Введение в GCC" компоновщик Команда для базовой программы "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.

person ardsrk    schedule 23.06.2009

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

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

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

person Lou Franco    schedule 23.06.2009
comment
Я думаю, что за этим вопросом стоит менталитет: содержимое libm в значительной степени является частью стандартной библиотеки C, почему его нет в libc? - person Evan Teran; 23.06.2009
comment
Почему для gcc - поддерживать совместимость с исходным cc в AT&T Unix. Я использовал 3B2 в 1988 году, и вам нужно было -lm, чтобы разобраться в математике. В то время это казалось мне совершенно произвольным. Я не помню, чтобы в Visual Studio когда-либо приходилось добавлять математику, но иногда вам нужно добавлять другие, казалось бы, библиотеки времени выполнения c. Я предполагаю, что у поставщиков компиляторов есть причина (время сборки?), Но сейчас я уверен, что gcc просто пытается обеспечить обратную совместимость. - person Lou Franco; 23.06.2009

Если я помещаю stdlib.h или stdio.h, мне не нужно связывать их, но я должен ссылаться при компиляции:

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

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

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

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

person Adrian Panasiuk    schedule 23.06.2009

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

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

person Community    schedule 23.06.2009
comment
он знает это .. он спрашивает почему - person Evan Teran; 23.06.2009
comment
Он говорит почему. Саймон объясняет, что некоторые библиотеки связаны по умолчанию, например stdio, тогда как математическая библиотека не связана по умолчанию, поэтому ее нужно указать. - person mnuzzo; 23.06.2009
comment
Я бы сказал, что суть вопроса заключается в том, почему libm не связана по умолчанию (или даже не отделена от libc), поскольку ее содержимое в значительной степени является частью стандартной библиотеки c. - person Evan Teran; 23.06.2009

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

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

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

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

Только предположение.

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

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

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

person Evan Teran    schedule 23.06.2009
comment
Если вы не связываетесь с libm, а касаетесь FPU x87 другими способами (например, операции с плавающими точками), ядру x86 необходимо сохранять состояние FPU. Не думаю, что это хорошее предположение ... - person ephemient; 23.06.2009
comment
конечно, если вы вручную используете FPU, ядру все равно нужно будет сохранить / восстановить его состояние. Я говорил, что если вы никогда его не используете (в том числе не используете libm), тогда этого не будет. - person Evan Teran; 23.06.2009
comment
На самом деле это может очень сильно зависеть от ядра. Математическая библиотека, которую использует ядро, может иметь функцию save_FPU_on_switch (), которая включает ее, в то время как другие просто определяют, был ли затронут FPU. - person Earlz; 23.06.2009
comment
Если я правильно помню, вся проблема задолго до того, как сопроцессоры с плавающей запятой были даже на микропроцессорах. - person Nosredna; 23.06.2009
comment
@earlz: подход с сохранением запроса математической библиотеки был бы ужасным дизайном. Что, если они используют FPU каким-либо другим способом? Единственный разумный подход (помимо постоянного сохранения / восстановления) - это обнаружить использование и затем начать сохранение / восстановление. - person Evan Teran; 23.06.2009

Обратите внимание, что -lm может не всегда указываться, даже если вы используете некоторые математические функции C.

Например, следующая простая программа:

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

int main() {

    printf("output: %f\n", sqrt(2.0));
    return 0;
}

можно скомпилировать и успешно запустить с помощью следующей команды:

gcc test.c -o test

Протестировано на gcc 7.5.0 (на Ubuntu 16.04) и gcc 4.8.0 (на CentOS 7).

Сообщение здесь дает некоторые пояснения:

Вызываемые математические функции реализуются встроенными функциями компилятора.

Смотрите также:

person jdhao    schedule 10.12.2020
comment
Это должен быть главный ответ - person yuanjianpeng; 19.03.2021

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

person Steve Summit    schedule 15.06.2021

Все библиотеки, такие как stdio.h и stdlib.h, имеют свою реализацию в libc.so или libc.a и по умолчанию связываются компоновщиком. Библиотеки для libc.so автоматически подключаются во время компиляции и включаются в исполняемый файл.
Но math.h имеет свои реализации в libm.so или libm.a, которые отделены от libc.so, и по умолчанию он не связывается, и вам нужно вручную связать его при компиляции вашей программы в gcc с помощью флага -lm.

Команда gnu gcc разработала его таким образом, чтобы он был отделен от других файлов заголовков, в то время как другие файлы заголовков связываются по умолчанию, а файл math.h - нет.

Здесь прочтите пункт № 14.3, вы можете прочитать его все, если хотите: Причина, по которой необходимо связать math.h
Посмотрите эту статью: почему мы должны связать math.h в gcc?
Взгляните на использование: с помощью библиотеки

person Saptarshi das    schedule 25.11.2020
comment
Об этом уже было сказано здесь в других ответах. И это даже не отвечает на вопрос. Вопрос в том, почему libm по умолчанию не связана. - person bolov; 26.11.2020
comment
Это означало, что math.h - это файл libraray, который отдельно записывается в libm.so, тогда как для других файлов заголовков он находится в libc.so, в то время как другие файлы заголовков подключаются автоматически, но math.h необходимо связать вручную, добавив - lm флаг - person Saptarshi das; 26.11.2020
comment
Все они являются частью стандартной библиотеки. Вопрос в том, почему не все связаны по умолчанию. Потому что это то, как это разработала команда gcc, - плохой ответ. Вопрос в том, в чем причина. И здесь есть отличные ответы, в которых подробно рассматриваются исторические причины. Ваше редактирование делает ваш ответ лучше, но я все еще не вижу, какое значение оно добавляет по сравнению со всеми другими ответами здесь. - person bolov; 26.11.2020