Dynamic vs. static linking
Programs can be either dynamically linked or statically linked. A dynamically linked program consists of a main executable and some shared libraries. The shared libraries are combined with the main executable when it is run, which allows the program to use code from the libraries. On the other hand, a statically linked program combines all the libraries into the program at build time.
The advantages of dynamic linking are:
- Code duplication is avoided by separating the compiled code. This saves disk space and memory.
- Libraries can be updated without relinking everything that uses them.
- The main program can dynamically load libraries to use them for plugins.
However, dynamic linking also has problems. It causes an issue known by various names including, on Windows, “DLL Hell,” in which different applications require different versions of the same library. The result is that at least one of them breaks because it doesn’t have the library version it needs. The common solution to this problem nowadays is to create a system that transparently stores copies of different specific versions of libraries as needed, such as .NET’s Global Assembly Cache. This unfortunately neutralizes some of the advantages of dynamic linking, because it consumes lots of extra disk and memory space and prevents central updating without relinking.
Dynamic linking also slows down program startup time because the operating system has to locate the libraries and link them. If they are not already in memory, they also have to be loaded. It further causes slowdowns at runtime, though much smaller, because calls to library functions have to go through a jump table.
In my opinion, the solution to all of these problems is simple: static linking. If all programs are statically-linked, they all have whatever version of their libraries they require built in, so problems cannot be caused by different library versions. In addition, they avoid the start time and runtime slowdowns because the linker can insert regular jump instructions and avoid the indirection and table-building needed with dynamic linking.
The problems dynamic linking were originally designed to solve are no longer as relevent; we have far more disk space and memory available, so smaller executables are less of a concern. Solving the DLL Hell problem already hurts disk and memory usage, so using static linking causes less of a problem than it seems. Static linking is also simpler, requiring less OS code and toolchain elements.
In conclusion, while dynamic linking provides some benefits, many of them are canceled out by problems dealing with different versions, and dynamic linking creates performance issues and complexity. All of this could be solved by moving to static linking for all purposes except plugins.