LINUX.ORG.RU

Декларации типов остаются в библиотеках?

 ,


0

6

Здравствуйте

Подскажите, пожалуйста. Такой странный вопрос. Вот наопределял я структуры и enum-ы в файле, скомпилировал в .so или в .a. Эти определения где-то сохранились в либе?

Нужно ли мне декларировать имена типов структур с префиксами, чтобы не было пересечений или эти имена не вылезут за пределы compilation unit?

И вообще, какие еще символы в либах сохраняются кроме определений функций и глобальных переменных?

★★★★★

Последнее исправление: makoven (всего исправлений: 3)

Ответ на: комментарий от hateyoufeel

и почему их обязательно нужно писать в хидерах.

Это вообще не относится к линковке, это компиляция, точнее препроцессинг даже.

anonymous
()
Ответ на: комментарий от anonymous

Это вообще не относится к линковке, это компиляция

Компиляция и разбиение кода на модули не относятся к линковке? Ок.

точнее препроцессинг даже.

Ха-ха-ха, хо-хо-хо. Ты ещё скажи что gcc - это препроцессор над as.

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous

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

Коллега, вы написали

Темплейты в C++ - это классический пример статической линковки

Так вот, включение .h файла в программу — это пример препроцессинга, вы сами сказали, что темплейты пишут в .h

Если мы говорим о простом C, то здесь это не так критично, потому как полность отсутствует полиморфизм.

И вот этот фееричный бред. Дескать, как только прибежит полиморфизм, динамическая линковка не канает. Какая чушь! Когда я еду через мост — автомобиль не канает. Только поезд!

anonymous
()
Ответ на: комментарий от hateyoufeel

Компиляция и разбиение кода на модули не относятся к линковке? Ок.

Нет. Компиляция — создание из translation unit'а его версии в машинных кодах (или в байткоде, как хочешь). А сбор из нескольких откомпилированных translation unit'ов одной программы — линковка

anonymous
()
Ответ на: комментарий от anonymous

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

Наконец-то ты понял! Тебе осталось всего чуть чуть: осознать в чём разница между C++ и лиспами в плане работы с объектами в памяти.

Алсо, в каком месте CL использует динамическую линковку? Там же любая программа таскает с собой компилятор CL фактически.

Так вот, включение .h файла в программу — это пример препроцессинга, вы сами сказали, что темплейты пишут в .h

Ага, а теперь попробуй понять почему темплейты пишут в .h. Не от хорошей жизни же.

И вот этот фееричный бред. Дескать, как только прибежит полиморфизм, динамическая линковка не канает.

Нет, как только прибежит полиморфизм, придётся запиливать боксинг. Научись читать, дорогой анонимус, я об этом писал в посте, который ты цитируешь.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)

Остаются только в том случае, если ты оставил отладочную информацию. Иначе лишь минимум нужный программе.

a1batross ★★★★★
()
Ответ на: комментарий от hateyoufeel

Расскажи почему шаблонные функции в C++ нельзя вынести в динамическую библиотеку

Потому что это не исполняеый код.

tailgunner ★★★★★
()
Ответ на: комментарий от makoven

Ещё про разницу, а то тебе мой коллега мозг засрет. Он явный профан, не слушай его))))

Минусы динамической линковки:

1) Короче, иногда динамический линкер просто недоступен. Было в каких-то линукс дистрах, может и сейчас есть. Программы в /bin и /sbin были все статическими, потому что линкер лежал ещё где-то, на ещё не смонтированной файловой системе. Или же они прикрывались тем, что «так безопаснее».

2) Куча бинарников вместо одного. Боль для распространителей проприетарного софта в бинарном виде. Риск получить несовместимость при обновлении. (Бамп версии библиотеки -> придется перелинковывать всё, ну или хранить несколько версий).

3) Более низкая производительность. Но не из-за «наличия отсутствия полиморфизма», как говорит коллега. Ему бы мозг вправить, приемы ООП к сабжу отношения не имеют. Дело в том, что в статической линковке при вызове функции или обращении к глобальной переменной происходит адресация по абсолютному адресу, а в динамической — обычно адресация относительно instruction pointer'а. Второе немного медленнее. Процентов на 10, может быть, царь скажет точнее. В x86 нет адресации относительно instruction pointer'а => требуется дополнительная хитрая пляска => ещё медленнее, нужно несколько инструкций для доступа к одной переменной.

Плюсы:

1) Меньший размер бинарников, есть общие библиотеки

2) Возможность сделать повышенную безопасность при помощи простых настроек в ядре, гугли по слову ASLR

anonymous
()
Ответ на: комментарий от hateyoufeel

Наконец-то ты понял! Тебе осталось всего чуть чуть: осознать в чём разница между C++ и лиспами в плане работы с объектами в памяти.

Я понял уже давно. А ты ничего не поймёшь

Алсо, в каком месте CL использует динамическую линковку? Там же любая программа таскает с собой компилятор CL фактически.

Я к тому, что в образе 99.9% кода расположено совершенно рандомно, и ничего полиморфизм полиморфизирует. А статическая линковка — способ положить код и статические данные по известным заранее (до запуска) адресам. Так что упоминание CL тут более чем уместно

anonymous
()
Ответ на: комментарий от anonymous

Я к тому, что в образе 99.9% кода расположено совершенно рандомно, и ничего полиморфизм полиморфизирует.

Мб это потому что все объекты в лиспах обладают RTTI (в терминах C++)?

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Нет, как только прибежит полиморфизм, придётся запиливать боксинг. Научись читать, дорогой анонимус, я об этом писал в посте, который ты цитируешь.

Чего ты пристал со своими темплейтами? Боксинг-шмоксинг. Вот тут ты написал, что, типа из-за них нужна статика.

Декларации типов остаются в библиотеках? (комментарий)

Ещё раз, на линковку это не влияет никак. Подгрузка .h файла — это стадия препроцессинга, а не линковки. Это самый первый шаг, а линковка — последний

anonymous
()
Ответ на: комментарий от anonymous

Ок. Спасибо. А отладочную информацию оставлять? Она влияет на скорость работы или еще на что-то кроме размера so-шки?

makoven ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

RTTI

Я не знаю C++, поясни, что ты хочешь сказать

anonymous
()
Ответ на: комментарий от makoven

Ок. Спасибо. А отладочную информацию оставлять? Она влияет на скорость работы или еще на что-то кроме размера so-шки?

Как хочешь. Нет, она ни на что не влияет. Можно оставить, если что-то часто падает, и ты хочешь разобраться

anonymous
()
Ответ на: комментарий от anonymous

Ещё раз, на линковку это не влияет никак. Подгрузка .h файла — это стадия препроцессинга, а не линковки.

Гугли про ключевое слово export в С++, с помощью которого можно было вынести темплейты в отдельные модули (объектные файлы), но их всё равно приходилось линковать статически.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Что я нашел

http://stackoverflow.com/questions/5416872/using-export-keyword-with-templates

Я не хочу спорить о C++, так как не знаю его. Как я понял, export устарел, советуют объявлять специализированный шаблон в файле, где он будет использован, и тогда реализацию можно будет унести в cpp. Сомневаюсь, что нужна будет именно статическая линковка, и что дело в ней.

Опять же, если поискать objdump -T /path/to/libstdc++.so | grep insert, найдём много вкусного. А это вроде как из шаблонных векторов

anonymous
()
Ответ на: комментарий от anonymous

Я не хочу спорить о C++, так как не знаю его.

Тогда зачем ты отвечал на комментарий, если не знаешь о чём в нём говорилось?

Как я понял, export устарел, советуют объявлять специализированный шаблон в файле, где он будет использован, и тогда реализацию можно будет унести в cpp.

Export не устарел, его выпилили, потому что он был реализован только в полутора компиляторах, в gcc сотоварищи его запиливать отказались из-за сложности реализации. О чём я тебе и писал, балда.

Сомневаюсь, что нужна будет именно статическая линковка, и что дело в ней.

Нужна именно она. Точнее, нормальная система модулей, которой в C++ до сих пор нет.

Опять же, если поискать objdump -T /path/to/libstdc++.so | grep insert, найдём много вкусного. А это вроде как из шаблонных векторов

Что именно из этого (https://bpaste.net/show/5aa33ff8d487) ты находишь вкусным? Про векторы там ни слова нет.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

Тогда зачем ты отвечал на комментарий, если не знаешь о чём в нём говорилось?

Ты сам потом писал про .h файлы. Кто виноват, что ты так изъясняешься?

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

anonymous
()
Ответ на: комментарий от anonymous

Ты сам потом писал про .h файлы. Кто виноват, что ты так изъясняешься?

Кто виноват что у тебя баклажан вместо мозга?

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

Golang не может в динамическую линковку (или не мог, давно не смотрел).

Я тебе не верю. Нафига тогда этот язык нужен.

Да, я тоже считаю что golang не нужен :)

Статические бинари весят дофига

Нет, потому что в него линкуются только используемые куски библиотеки.

Но вообще, почти во всех языках со статической типизацией и параметрическим полиморфизмом (Haskell, *ML, Rust, etc) статическая линковка используется по дефолту.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)

tailgunner, ты c++ знаешь? Правду говорит мой коллега, что c++ шаблоны работают только со статической линковкой?

У меня и бинарей нет таких, значит у меня все программы без шаблонов? )))

anonymous
()
Ответ на: комментарий от hateyoufeel

Кто виноват что у тебя баклажан вместо мозга?

Нормально, целую страницу писал мне, что шаблоны целиков в .h, а потом на мой мозг жалуется ))

anonymous
()
Ответ на: комментарий от hateyoufeel

Потому что это не исполняеый код.

А как же export?

АПВОВНВ? Если ты хотел сказать «но ведь с export шаблонный код становится исполняемым» - скажи прямо. Если хотел сказать что-то другое - опять же, скажи прямо.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

АПВОВНВ?

Нет ты.

Если ты хотел сказать «но ведь с export шаблонный код становится исполняемым» - скажи прямо.

Что ты имеешь ввиду под словом «исполняемый»?

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Если ты хотел сказать «но ведь с export шаблонный код становится исполняемым» - скажи прямо.

Что ты имеешь ввиду под словом «исполняемый»?

ISA.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Если ты хотел сказать «но ведь с export шаблонный код становится исполняемым» - скажи прямо.

Что ты имеешь ввиду под словом «исполняемый»?

ISA.

Что? Я сейчас о коде на C++ говорю.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Что? Я сейчас о коде на C++ говорю.

Хм.

hateyoufeel > Расскажи почему шаблонные функции в C++ нельзя вынести в динамическую библиотеку

tailgunner> Потому что это не исполняеый код.

Но, оказывается, ты говорил о коде на Си++. В динамической библиотеке. Свободен, чертов наркоман.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Но, оказывается, ты говорил о коде на Си++. В динамической библиотеке. Свободен, чертов наркоман.

Это ты так сливаешься или что? Я тебя не понимаю.

hateyoufeel ★★★★★
()
Ответ на: комментарий от mittorn

Не вижу им альтернативы кроме как не играть по сети.

А она есть. Не отправлять клиенту больше, чем он должен знать. Проверять все данные от клиента на корректность. Идеально защищённая игра - сервер стримит картинку, а клиент тупо передаёт движения мыши и нажатия на клавиши. Но, разумеется, в реальности это слишком накладно, поэтому применяют некоторые оптимизации (хранить модели на клиенте, рендерить на клиенте, передавать лишь координаты и тип видимых объектов).

Конечно, отдельный вопрос касается ботоводов. Но анальные античиты, которые требуют установку ядерного модуля для слежения за всей системой - уж точно не нужны. Пусть лучше читерят.

KivApple ★★★★★
()
Ответ на: комментарий от anonymous

Дело в том, что в статической линковке при вызове функции или обращении к глобальной переменной происходит адресация по абсолютному адресу, а в динамической — обычно адресация относительно instruction pointer'а.

На архитектуре x86 действительно нет адресации относительно IP. Только всякими косвенными методами (типа вычислить базу кода каким-нибудь костылём, а затем прибавить смещение). Только вот есть такая штука как релокации. Можно обойтись без всякого PIC-кода, а просто заполнить таблицу релокаций, указав все места, где обращаются к глобальным переменным. И линкер заботливо прибавит ко всем нужным адресам базу, по которой загружен код. Команды переходов на x86 и так всегда относительные (кроме «дальних» вызовов, но многосегментная модель кода не поддерживается ни одним современными компилятором). Так что чисто теоретически можно не терять производительность.

А вот на x86_64 ситуация ещё интереснее. Нет там инструкций абсолютной адресации. Там вся адресация строится относительно RIP (теперь это стало возможно делать напрямую и без костылей), либо другого регистра. Хочешь обратиться по абсолютному адресу - грузи его в регистр как константу, а затем обращайся относительно этого регистра. Так что x86_64 код уже по дефолту почти PIC. Проблемы лишь с адресами, которые заданы явно в секции данных. Например, если ты инициализируешь глобальную переменную адресом другой глобальной переменной. Но эта проблема отлично решается релоками.

Таким образом написание PIC-кода если и приводит к просадкам производительности, то лишь в особых случаях. А если компилятор достаточно умён, то лишь ОС придётся поработать чуть дольше при загрузке бинарника.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от anonymous

Шаблоны очень близки к макросам. Да, они имеют другой синтаксис и возможности (в том числе способность оперировать с типом аргумента), однако по сути они лишь управляют генерацией кода компилятором, при этом сами по себе кодом не являются. Разумеется, они исчезают в момент компиляции и существуют лишь в заголовочных файлах. Точно также как #define'ы из Си.

KivApple ★★★★★
()
Ответ на: комментарий от KivApple

так предлагается следить только в пределах процесса. Разумеется это не идеальный вариант т.к его могут отреверсить и хакнуть.

mittorn ★★★★★
()
Ответ на: комментарий от KivApple

Так что чисто теоретически можно не терять производительность.

Нет. Релокация — это тебе не поиск по коду, где идет обращение к какому-либо адресу. Это изменение секции .got и подобных. Адресация всё равно идет через %rbx

anonymous
()
Ответ на: комментарий от KivApple

А вот на x86_64 ситуация ещё интереснее. Нет там инструкций абсолютной адресации. Там вся адресация строится относительно RIP

Ну да, точно. Но смысл всё равно тот же, в статике мы знаем зарание где что лежит, а в динамике - нет, поэтому обращаемся к .plt и .got

anonymous
()
Ответ на: комментарий от hateyoufeel

Ты удивишься, но в CL только динамическая линковка и есть.

Вся адресация функций там - непрямая(кроме заинлайненных, и локальных и одновременно оптимизированных, функций). Когда мы в коде вызываем функцию, 50 на 50 получается что мы либо «вызываем» символ, либо т.н. fdefinition. Если символ - из него в рантайме достается fdefinition. Последний это, собственно, некая метаинформация о функции, где в том числе есть трамплин(«trampoline», из сленга компиляторщиков) на ее код.

Если мы говорим о компиляции в рантайме, то символ(лисповый который) - связывается с кодом прямо на твоих глазах.

Та же ситуация при GC - код и символы перемещаются по разным местам в памяти, а потом перелинковываются.

Если мы говорим про загрузку объектного файла(fasl), то там похожая ситуация - идет загрузка определений и перелинковка с символами и fdefinition(и релокация по свободным местам в куче).

Если про загрузку образа(ну там, .core в SBCL) - примерно как в вышеописанном случае с файлами, за исключение разве что того, что в некоторых реализациях это все дело помещается куда-нибудь в read-execute страницы и все смещения заранее известны, т.е. из них создание связи кода с символами и fdefinition делается прямо и просто.

lovesan ★★
()
Ответ на: комментарий от lovesan

А, и если про FFI и связь с сишным кодом - то тем более только динамическая линковка.

SBCL вон тупо хранит лисповую хэш-табличку linkage-table, в которой имена символом мапятся на адреса в памяти. И при перезагрузке образа ее перечитывает.

lovesan ★★
()
Ответ на: комментарий от hateyoufeel

Динамическая линковка грозит усложненим реализации языка и потерей производительности, иногда - довольно серьёзной

да прям, хорош страшилками нубов пугать. подгруженная в память библиотека по сути ничем не отличается от вызовов внутри модуля. если не заниматься задротством с оптимизацией близких вызовов. но, как правило, оно не даёт даже микропроцента прибавки к скорости. иными словами, овчинка выделки не стоит. остальное - понты. по скорости что статика, что динамика работают примерно одинаково. разница только в удобстве: если нужно заменить один модуль (библиотеку), то при динамике это просто. а при статике надо пересобирать всё. поэтому, наверное, линюксоиды додумались до коллекции динамических библиотек для общего пользования на все случаи жизни. и никто не жужжит. в любом случае, к системным библиотекам линковка динамическая. а там как раз больше всего самых «тяжёлых» вызовов. так что не надо заниматься оптимизацией незнамо чего.

Iron_Bug ★★★★★
()
Ответ на: комментарий от lovesan

Концепцыя COM/OLE — частный случай CORBA (MS-версия СБИШ), комитет по разработке которой («консорциум OMG») микрософту не удалось прогнуть под себе (там сделали коллективный фейспалм и сказали «ОМГ!» :)) А «целый .Net» — это «жабка+дельфи вид сбоку» — первую санки с Ораклом не дали опять таки «объять и расширить», засудив MS за отсебятину в J++, а там под руку подвернулся обиженый руководятлами Borland Хайзенберг Хайлзберг и «обход этого» там сбоку припека: например, «обходя это» они отломили нафиг возможность экспортов из сборок дотнета в натив без чорной IL-магии (или оберток на ужоснахе «манагед C++»)

slackwarrior ★★★★★
()
Ответ на: комментарий от Iron_Bug

«то при динамике это просто» (с) Ну, опять таки в сказке где все с прямыми руками :) А когда либа завязана на рантаймы определенных версий — начинается веселье (которое впрочем к срачу за скорость не имеет отношения, да :))

slackwarrior ★★★★★
()
Ответ на: комментарий от Iron_Bug

Динамическая линковка как минимум ставит крест на cross-module inlining, который местами даёт весьма весомый прирост к производительности кода.

P.S. Я понимаю, что с программированием у тебя проблемы, но хотя бы русский язык постарайся осилить, ок? Хотя бы по части заглавных букв.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

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

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

я принципиально не использую заглавные буквы. предложения разделяются точками и этого хватает. если есть баттхёрт - можешь через sed прогнать и наслаждаться буквоедством.

Iron_Bug ★★★★★
()
Ответ на: комментарий от slackwarrior

а зачем завязывать либы на рантаймы определённых версий? разве что если у разработчика слабоумие. ну и какбэ опенсорц и всё такое. нужно пересобрать - пересобери. делов-то.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 2)
Ответ на: комментарий от Iron_Bug

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

Переход на личности. Молодец, у тебя бесподобные навыки ведения спора.

как показывает практика, оптимизация на инлайнах - чаще всего ненужная и неэффективная экономия на спичках.

Чья практика? Citation needed.

а если код написан нормально, то они, как правило, и вовсе не нужны.

Нормально - это как именно? Я бы хотел чуть более развёрнутый ответ, чем твоё «Я ОХРЕНИТЕЛЬНЫЙ ПРОГРАММИСТ ВЫ НИХРЕНА НЕ ПОНИМАЕТЕ».

я принципиально не использую заглавные буквы.

На этом сайте запрещено преднамеренное нарушение правил русского языка. Пункт 5.5 (www.linux.org.ru/help/rules.md).

если есть баттхёрт - можешь через sed прогнать и наслаждаться буквоедством.

Луркояз от взрослого человека - это так мило. Сразу понятно с кем имеешь дело.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

наверное, кто-то до меня начал переходить на личности, не? я всегда спускаюсь на уровень взаимодействия, доступный оппоненту. зеркало всегда немного раздражает, не правда ли?

ну, давай, забань меня за орфографию :D более идиотской придирки я пока ещё не видела. и это при том, что я отлично знаю русский язык (и ещё несколько других) и вижу, сколько тут грамотеев тусит. просто я не хочу играть в граммар-наци. это бессмысленно. я могу хоть на олбанском посты читать. у меня нет пунктика на этот счёт.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

Круто, я очень рад за тебя.

А теперь, пожалуйста, про твой опыт оптимизации и про code inlining в частности расскажи.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

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

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

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

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.