LINUX.ORG.RU

Модульность-2

 


0

1

Вопрос такой. Заголовочные файлы в С позволяют:

1. Увидеть, какой интерфейс у библиотеки

2. Прилинковаться к ней.

В Pascal есть скомпилированный модуль. Не знаю, можно ли из него достать интерфейс (скорее нет), но можно прилинковаться. Т.е., нужен либо исходник, либо урезанный исходник, если closed source.

В Лиспе - примерно то же самое, что и в Паскале. Если повезёт, то удастся узнать сигнатуры функций.

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

А как Java, Golang и Rust с этим обходятся? Есть ли там вообще понятие «библиотека» (то, что в C есть .lib) и возможность её предоставить без предоставления исходников?

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

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

Либо формат «объектного файла» или «библиотеки» должен содержать в себе информацию из заголовочника, чтобы его можно было использовать. Но это решение имеет свои недостатки.

Ваши мнения?

★★★★★

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

Увидеть, какой интерфейс у библиотеки

Обычно белые люди используют документацию в таком случае.

Solace ★★
()

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

Имхо, либо автогенерируемые хедеры (что полумера), либо метаданные в объектниках. Афаик, C++ идет к последнему.

anonymous
()

модула-1,2,3 уже было: не взлетело

Полезно задуматься, почему.

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

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

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

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

den73 ★★★★★
() автор топика

Я за метаданные.

решение имеет свои недостатки

Какие?

true_admin ★★★★★
()

я, может, что-то пропустил, но каким образом «заголовочный файл в C» позволяет «прилинковаться к библиотеке»?

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

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

Solace ★★
()

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

В Java/.NET в либах лежат тонны метаинформации и обязательно все definitions, без них просто ничего не работает. Однако, метаинформация метаинформации рознь, и не вся из нее обязательна для работы. Ту, что необязательна, можно успешно вычистить, это незначительно затруднит реверсинг. Впрочем, именно незначительно - все bytecode based языки реверсятся очень хорошо.

В Erlang на одном из этапов компиляции в модуль добавляется функция module_info/[1,2] , которые позволяют получить список экспортируемых функций и их arity. А debug info содержит abstract format исходника, который приводится в читаемый текст в одну строку.

По меньшей мере для статически-типизированного языка, dev-версия библиотеки ОБЯЗАНА содержать описание своего интерфейса, от этого никуда не деться. Однако, для реверсинга или просто незапланированного использования важнее не интерфейс, а debug info, и вот ее-то вполне можно из библиотеки вычистить.

nwalker
()

А как Java, Golang и Rust с этим обходятся? Есть ли там вообще понятие «библиотека» (то, что в C есть .lib) и возможность её предоставить без предоставления исходников?

В class-файлах (скомпилированные в байткод классы) и, соответственно в jar-файлах (а ля «библиотеки») Java есть вся необходимая метаинформация, ведь как иначе программист и компилятор будут знать, какие в «библиотеке» существуют классы и как с ними работать? Документация при этом обычно поставляется отдельным дополнительным jar-файлом с именем <libname>-javadoc.jar, как тут тебе уже намекали. Опенсорсные библиотеки также обычно предоставляют <libname>-src.jar, который можно «прикрепить» к подключённой либе в IDE, чтобы иметь возможность их просмотреть, при желании. Но для отображения интерфейсов классов IDE достаточно class-файлов.

Про golang ничего не скажу, так как пользовался только опенсорсными библиотеками.

Про Rust ничего не скажу, потому что не пользовался.

korvin_ ★★★★★
()

Для паскаля совершенно точно есть и используются свои заголовки, которые представляют собой тот же *.pas, но только со словами unit и type, и без implementation. По Delphi помню. Правда, кажется, нет (не было?) пространств имён или пакетов, соответственно, можно наслаждаться коллизиями в именах модулей. Судя по C, правда, похоже это не очень страшная проблема.

d_a ★★★★★
()

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

Зачем нужен побочный продукт от процесса сборки, если можно использовать результат процесса сборки?

anonymous
()

Заголовочные файлы в С позволяют:

1. Увидеть, какой интерфейс у библиотеки

если интерфейс правильно реализован, потому что сам компилятор это никак не контролирует

2. Прилинковаться к ней.

прилинковаться к заголовку?

lazyklimm ★★★★★
()

В Лиспе - примерно то же самое, что и в Паскале. Если повезёт, то удастся узнать сигнатуры функций.

в каком из лиспов?

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

C хедеры не обязательно нужны, главное, чтобы mangling был одинаковым

Там есть какой-то mangling?

anonymous
()

ТС конкретный словоблуд и ничтожество, тут все на ЛОРе такие, даже анонимус

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

прилинковаться к заголовку?

Да забей, он вряд ли имеет понятие, как происходит это дело

anonymous
()

2. Прилинковаться к ней.

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

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

Да, я неправильно сказал насчёт линковаться. Скажу так: чтобы безопасно использовать эту библиотеку без извращений, при условии, что заголовочник действительно соответствует библиотеке.

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

Для паскаля совершенно точно есть и используются свои заголовки, >которые представляют собой тот же *.pas, но только со словами unit и >type, и без implementation.

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

В то время как в С заголовочник более органичен - он сразу является частью технологии, а не костылём.

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

Имхо, либо автогенерируемые хедеры (что полумера), либо метаданные в объектниках. Афаик, C++ идет к последнему.

Здесь есть ещё один неожиданный подводный камень. У нас есть my.h и my.c. Если мы поменяли реализацию, то нам нужно перекомпилировать my.c. Если мы поменяли интерфейс, то нам нужно перекомпилировать все файлы, где включён my.h.

Если у нас новый продвинутый СуперЯз, где my.h и my.c объединены в один файл, то...

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

Моё мнение: обсуждение не имеет смысла.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от den73

Если у нас новый продвинутый СуперЯз, где my.h и my.c объединены в один файл, то...

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

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

Надо перекомпилироват ьтолько этот файл если менялась только реализация

Да, только это не так просто установить, как в случае С. Для С достаточно посмотреть на время модификации .h,.c,.obj. Для СуперЯз а нужно сравнить время модификации .СуперЯ с .obj. Если .СуперЯз моложе чем .obj, то нужно скомпилировать интерфейсную часть .СуперЯз, извлечь интерфейс из .obj, сравнить сигнатуры.

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

Мне сегодня пришёл в голову ещё один момент. Проект развивается во времени. И есть такой инструмент, как журнал системы контроля версий. Окинув его взглядом для проекта на C, сразу можем понять, изменился ли интерфейс. В СуперЯзе нам придётся просматривать все изменения и анализировать каждое изменение с точки зрения того, влияет ли оно на интерфейс.

И есть ещё философское соображение за заголовочники. Они воплощают идею разделения интерфейса и реализации.

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

Там есть какой-то mangling?

Платформозависимо.

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

заголовочники. Они воплощают идею разделения интерфейса и реализации.

Конкретно сишные заголовочники - хреново воплощают, там слишком много реализации.

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

Мне сегодня пришёл в голову ещё один момент. Проект развивается во времени. И есть такой инструмент, как журнал системы контроля версий. Окинув его взглядом для проекта на C, сразу можем понять, изменился ли интерфейс. В СуперЯзе нам придётся просматривать все изменения и анализировать каждое изменение с точки зрения того, влияет ли оно на интерфейс.

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

И есть ещё философское соображение за заголовочники. Они воплощают идею разделения интерфейса и реализации.

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

И это все имеет хоть какое-то значение только если ты кодишь в блокноте. Все нормальные ИДЕ сохраняют метаданные для проекта.

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

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

В данном конкретном случае можно воспользоваться идиомой PIMPL. Бонусом получишь возможность не ломать ABI при изменении приватной части класса.

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

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

den73 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.