Встроенная функция компиляции

Я намереваюсь предоставить простые оболочки для API операционной системы, которые генерируют исключения при возникновении ошибок. Эти обертки просты, и все они определены как встроенные функции в заголовочном файле. Поскольку системный API должен быть большим, заголовочный файл также должен быть огромным и содержать большое количество крошечных встроенных функций. Проблема в том, что если общая библиотека (.so) скомпилирована с включенным заголовочным файлом, все эти крошечные обертки будут скомпилированы в результирующий двоичный файл, что приведет к большому двоичному файлу, даже если на самом деле только небольшая часть оберток используемый? А как насчет случая с исполняемыми файлами, будет ли он другим? Если это так, будет ли единственным решением проблемы разделение оболочек на несколько заголовочных файлов? Или я должен сделать внутреннюю связь оболочек, указав static?

Вот что я думаю. Обертки могут использоваться ODR (например, принимая его адрес). А на платформах Linux функции с внешними связями экспортируются по умолчанию (то есть, связываются с другими бинарными модулями). Поэтому я думаю, что для компоновщика может потребоваться сгенерировать определения структуры для них. Пожалуйста, обратитесь к пункту 3) в Описание раздел Вот.

Простой пример упаковки CloseHandle() в Windows API:

inline void close_handle(HANDLE handle) {
if (!CloseHandle(handle)) {
throw std::system_error(GetLastError(), std::system_category(), "CloseHandle");
}
}

0

Решение

(Довольно маленькая) объявленная функция static inline (или часто просто inlineили даже определенная функция-член внутри немного class или же struct) не будет (на практике) появляться в коде, если он не используется (см. этот) и, вероятно, будет указываться везде. Конечно, вам нужно включить оптимизацию в вашей команде компиляции. Итак, если вы используете НКУ, компилировать с g++ -Wall -O2 (и вы могли бы добавить -fverbose-asm -S и загляните внутрь сгенерированного ассемблерного кода для проверки).

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

Кстати, может показаться, что вы изобретаете фреймворк, похожий на ПОКО или Qt. Вы решили использовать их вместо этого?

Кроме того, последние реализации C ++ 11 (и C ++ 14) уже содержат значительную часть API OS (в частности, стандарт C ++). Библиотека IO и C ++ библиотека поддержки потоков и совсем недавно C ++ 14 TS), часто уже использующие исключения, поэтому лучше использовать их и использовать недавний Компилятор C ++ (для GCC это означает GCC 5,2 в ноябре 2015 года).

(Другими словами, используйте код как минимум для C ++ 11, а не для C ++ 98)

В Linux с НКУ (или же Clang / LLVM), если вы делаете библиотеку, вас может заинтересовать оптимизация времени компоновки (компиляция & ссылка на сайт библиотека с g++ -O2 -flto), предварительно скомпилированные заголовки, видимость функция атрибуты.

По поводу библиотек программ в Linux читайте Библиотека программ HowTo. За общий библиотеки, прочитайте статью Дреппера: Как писать общие библиотеки а также этот ответ.

На практике встроенная функция в некоторой библиотеке часто не выделяется в библиотеке, а в прикладной программе, вызывающей ее. Так что если ваша общая библиотека Foo определяет в публичном заголовке <foo.h>

 inline int maxsq(int a, int b) {
// you could add some conditional throw here...
if (std::abs(a) < std::abs(b)) return b*b;
else return a*a;
}

тогда объектный код maxsq наверное не появится внутри libfoo.so, но только в вашей программе (которая #include <foo.h> в исходном коде), если эта программа нуждается maxsq быть намеченным, например хранит адрес maxsq где-то (или если вы не просили достаточно оптимизации).

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]