What is Linking?
We often use the term compiling to encompass both compiling and linking, but linking is a discrete step. A compiler or assembler produces object code. (Usually in the form of .obj files.) Combining these object files into a single library (or executable) is referred to as linking.
On Windows systems, dynamically linked libraries use the file extension .dll. On Linux, dynamically linked libraries are referred to as shared objects and use the file extension .so. Both platforms standardize on the use of the .lib extension for statically linked libraries.
Dynamically linked libraries offer a number of benefits over static linking but also come with some regrets. There are times when a statically linked library makes sense.
Dynamically Linked Libraries
When multiple processes load the same library at the same base address, they share a single library instance in memory. When many applications may utilize the same library at the same time, this can be highly beneficial. It reduces the memory footprint of the library code and reduces load time when multiple applications are utilizing it. However, it also ties together all library users on a system, meaning that if one updates the library, all must use the new version. There are situations where this may not be desired. (Try to avoid DLL Hell.)
UPGRADES AND PATCHES
When any of the implementation of the symbols within a dynamically linked library is updated, applications that utilize them do not need to be recompiled or relinked (so long as the symbol signatures do not change). A statically linked library would require relinking (at a minimum) when symbol implementations change.
Programs written in different languages but which utilize the same calling convention (i.e., cdecl, stdcall, or pascal) can leverage the same dynamically linked libraries.
A shared library’s actual performance can be higher because operating systems may choose not to page out memory used by several applications. This OS behavior can result in fewer page faults during application execution. (And paging behavior can be a significant contribution to overall application performance.)
Statically Linked Libraries
Dynamically linked applications are not self-contained. It may not be obvious which dynamic libraries are being utilized by an application without detailed inspection at runtime (and executing different pathways within the application). Statically linked libraries explicitly include all code necessary to execute and are generally easier to distribute.
Dynamic linking takes time. There must be runtime loading of the library from disk into memory, linking, and then executing. There are times when this can be a significant performance hit to an application. Statically linked libraries do not suffer these specific bottlenecks.
Symbols utilized inside a dynamically linked library may be distributed throughout a virtual address space. This virtual address space distribution means that an application may have to move through many pages to access the specific symbols it needs and create Translation Lookaside Buffer (TLB). Statically linked libraries bind the references into a program with more address space locality. (Other advanced optimization techniques may improve this even more.)
CONSISTENT LOAD TIMES
Dynamically linking libraries takes time and not necessarily a predictable amount of time. Statically linked applications, however, will take a constant time to load. If your application must be highly deterministic within the system it executes (think safety-critical applications), then static linking your application may be worth considering.
To dynamically link a library, the Application Binary Interface (ABI) of the library must be compatible with that of the application attempting to link it at runtime. API compatibility was a significant source of irritation for Windows C++ developers before Visual Studio 2017. Now, modern compilers are sensitive to creating ABI-breaking changes.
Which Linking Strategy is Right for an Application?
It depends (of course). If performance is your key driver when deciding on static vs. dynamic linking, the only real answer is to measure. You may find that some libraries need to be statically linked, while others should be dynamically linked. Even the internal structure of an application can impact this.
2900 Presidential Drive, Suite 155
Beavercreek, OH 45324
(833) 694 8496