简体   繁体   English

为什么不是所有的Boost库都不都是标头的?

[英]Why are not all Boost libraries header-only?

Why are all libraries in Boost not headers-only? 为什么Boost中的所有库都不都是仅标头的? Saying it differently, what makes the use of .lib/.dll mandatory? 换句话说,什么使强制使用.lib / .dll?

Is it when a class can't be a template or has static fields? 是当类不能作为模板或具有静态字段时吗?

Different points, I guess. 我猜是不同的观点。

  • Binary size. 二进制大小。 Could header-only put a size burden on the client? 仅标头会给客户端带来很大的负担吗?
  • Compilation times. 编译时间。 Could header-only mean a significant decrease in compilation performance? 仅标头可能意味着编译性能显着下降吗?
  • Runtime Performance. 运行时性能。 Could header-only give superior performance? 仅标头能否提供出色的性能?
  • Restrictions. 限制条件。 Does the design require header-only? 设计是否仅要求标头?

About binary size. 关于二进制大小。

and a bit of security 和一点安全

If there's a lot of reachable code in the boost library, or code about which the compiler can't argue whether it is reachable by the client, it has to be put into the final binary. 如果boost库中有很多可访问的代码,或者编译器无法争论客户端是否可以访问的代码,则必须将其放入最终二进制文件中。 (*) (*)

On operating systems that have package management (eg RPM- or .deb-based), shared libraries can mean a big decrease in binary distribution size and have a security advantage: Security fixes are distributed faster and are then automatically used by all .so/.DLL users. 在具有程序包管理的操作系统(例如,基于RPM或.deb的操作系统)上,共享库可能意味着二进制分发大小会大大减少并且具有安全优势:安全修补程序分发速度更快,然后所有.so /会自动使用。 .DLL用户。 So you had one recompile and one redistribution, but N profiteers. 因此,您进行了一次重新编译和一次重新分配,但是您获得了N个获利者。 With a header-only library, you have N recompiles, N redistributions, always for each fix, and some member of those N are huge in themselves already. 使用仅标头的库,您总是为每个修复程序进行N次重新编译, N次重新分发,并且其中N个成员中的某些成员本身已经非常庞大。

(*) reachable here means "potentially executed" (*)此处的含义是“潜在执行”

About compilation times. 关于编译时间。

Some boost libraries are huge. 一些Boost库很大。 If you would #include it all, each time you change a bit in your source-file, you have to recompile everything you #include d. 如果要全部包含#include ,则每次在源文件中进行一些更改时,都必须重新编译#include d的所有内容。

This can be counter-measured with cherry picked headers, eg 这可以用挑选的樱桃标头来抵消,例如

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

but sometimes the stuff you really need to include is already big enough to cripple your recompiles. 但是有时候您真正需要包含的内容已经足够大,足以削弱您的重新编译能力。

The countermeasure is to make it a static or shared library, in turn meaning "compile completely exactly once (until the next boost update)". 对策是使其成为静态或共享库,这又意味着“完全完全编译一次(直到下一次增强更新)”。

About runtime performance. 关于运行时性能。

We are still not in an age were global optimization solves all of our C++ performance problems. 全局优化还不能解决所有C ++性能问题。 To make sure you give the compiler all the information it needs, you can make stuff header-only and let the compiler make inlining decisions. 为了确保将所需的所有信息提供给编译器,您可以将内容设置为仅标头,然后让编译器做出内联决策。

In that respect, note that inlining gives not always superior performance because of caching and speculation issues on the CPU. 在这方面,请注意,由于CPU上的缓存和推测问题,内联并不总是提供出色的性能。

Note also that this argument is mostly with regards to boost libraries that might be used frequently enough, eg one could expect boost::shared_ptr<> to be used very often, and thus be a relevant performance factor. 还要注意,该参数主要是关于可能经常使用的Boost库,例如,人们可能期望boost::shared_ptr<>非常频繁地使用,因此是一个相关的性能因素。

But consider the real and only relevant reason boost::shared_ptr<> is header-only ... 但是请考虑boost::shared_ptr<>的真正且唯一相关的原因是仅标头...

About restrictions. 关于限制。

Some stuff in C++ can not be put into libraries, namely templates and enumerations. C ++中的某些内容无法放入库中,即模板和枚举。

But note that this is only halfway true. 但是请注意,这只是一半。 You can write typesafe, templated interfaces to your real data structures and algorithms, which in turn have their runtime-generic implementation in a library. 您可以为实际的数据结构和算法编写类型安全的模板化接口,这些接口又在库中具有运行时通用的实现。

Likewise, some stuff in C++ should be put into source files, and in case of boost, libraries. 同样, 应将 C ++中的某些内容放到源文件中,如果使用boost, 放到库中。 Basically, this is everything that would give "multiple definition" errors, like static member variables or global variables in general. 基本上,这就是会产生“多个定义”错误的所有内容,例如static成员变量或全局变量。

Some examples can also be found in the standard library: std::cout is defined in the standard as extern ostream cout; 在标准库中也可以找到一些示例: std::cout在标准中定义为extern ostream cout; , and so cout basically requires the distribution of something (library or sourcefile) that defines it once and only once . cout基本上需要的东西 (库或的资源文件)的分布,它定义了一次,只有一次

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM