In a shared library, the linker simply inserts in the executable enough information to find the library and load it when the executable is invoked. This typically happens before the program ever gets to main(). This keeps executables small and allows commonly used libraries to be reused without copying, but it also means that the executable can fail if the library is renamed, moved, deleted, or even if the user's environment changes sufficiently.
A necessary (but not sufficient) condition for shared libraries to work is that all the compilation units (*.o) contained must be explicitly compiled as position independent code(PIC). Position independent code has an added level of indirection in critical areas since details (such as addresses to jump to in subroutine calls) are not known until runtime. Even though shared libraries are very useful, PIC causes a small but measurable degradation in performance, making static linked libraries with non-PIC code a viable option for performance-critical situations.
A dynamic-linked library is a shared library with one added feature, it can be loaded explicitly by the user at runtime by passing the string name into dlopen(). Dynamic-linked libraries (DLL's) also require compilation as PIC, though many compilers (including GCC) have special commands for each15.1.