Подтвердить что ты не робот

Почему не все расширенные библиотеки только для заголовков?

Почему все lib в Boost не являются только заголовками? Говоря иначе, что делает обязательным использование .lib/.dll?

Это когда класс не может быть шаблоном или имеет статические поля?

4b9b3361

Ответ 1

Я думаю, что разные точки.

  • Двоичный размер. Может ли только заголовок накладывать бремя на клиенту?
  • Время компиляции. Может ли только заголовок означать значительное снижение производительности компиляции?
  • Производительность выполнения. Может ли только заголовок обеспечить превосходную производительность?
  • Ограничения. Требуется ли только дизайн заголовка?

О двоичном размере.

и немного безопасности

Если в библиотеке boost имеется много доступного кода или код, о котором компилятор не может утверждать, доступен ли клиент клиенту, он должен быть помещен в окончательный двоичный файл. (*)

В операционных системах, которые имеют управление пакетами (например, RPM- или .deb-based), разделяемые библиотеки могут означать значительное уменьшение размера дистрибутива двоичных файлов и иметь преимущество безопасности: исправления безопасности распределяются быстрее и затем автоматически используются всеми .so/.DLL. Таким образом, у вас была одна перекомпиляция и одно перераспределение, но N спекулянтов. С библиотекой только для заголовков у вас есть N перекомпиляций, N перераспределений, всегда для каждого исправления, и некоторый член из них N уже сам по себе уже.

(*) достижимый здесь означает "потенциально выполненный"

О времени компиляции.

Некоторые библиотеки ускорения огромны. Если вы все равно #include, каждый раз, когда вы меняете бит в исходном файле, вам нужно перекомпилировать все, что вы #include d.

Это может быть встречно измерено с помощью вишневых заголовков, например

#include <boost/huge-boost-library.hpp> // < BAD
#include <boost/huge-boost-library/just-a-part-of-it.hpp> // < BETTER

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

Контрмера должна сделать его статической или разделяемой библиотекой, в свою очередь, означает "полностью компилировать один раз (до следующего обновления обновления)".

О производительности во время выполнения.

Мы все еще не достигли возраста, и глобальная оптимизация решает все проблемы производительности С++. Чтобы убедиться, что вы предоставили компилятору всю необходимую ему информацию, вы можете сделать материал только заголовком и позволить компилятору вносить решения в форму.

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

Отметим также, что этот аргумент в основном связан с расширением библиотек, которые могут быть использованы достаточно часто, например. можно ожидать, что boost::shared_ptr<> будет использоваться очень часто и, следовательно, будет соответствующим коэффициентом производительности.

Но рассмотрим реальную и единственную релевантную причину boost::shared_ptr<> только для заголовка...

Об ограничениях.

Некоторые вещи в С++ не могут быть помещены в библиотеки, а именно шаблоны и перечисления.

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

Аналогично, некоторые вещи в С++ должны быть помещены в исходные файлы, а в случае boost - библиотеки. В принципе, это все, что дало бы ошибки "множественного определения", такие как переменные-члены или t2 > вообще.

Некоторые примеры также можно найти в стандартной библиотеке: std::cout определяется в стандарте как extern ostream cout;, и поэтому cout в основном требует распространения чего-то (библиотеки или исходного файла), который определяет его один раз и только один раз.