Weak links and null addresses
Predominately used by the C standard library, the C++ compiler,
symbols (functions and variables) can be weakly linked. This
allows functions to be replaced with custom implementations
(and it's commonly use to switch the memory allocator), which
is useful for test development and system call virtualisation.
But you can define a stub function in a library and let another,
optionally linked, library provide a the implementation. For
example, in liberrror, I made a functions that do stack unwinding
and backtracking, however liberrror only had stubs that didn't
do anything, and if you wanted the feature, which required
additional libraries, you also linked your application with
liberror-backtrace. And using the LD_PRELOAD environment variable,
the user could opt in as at any time unless the application had
privileges that disabled LD_PRELOAD in the dynamic linker.
With GCC or clang, you can make a function or variable weakly
linked by adding __attribute__((weak)). If you want
your code be able to remain access to your own implemenation
you can make the weakly linked function execute a strongly
linked function, however a more efficient approach which also
works for variables (however I cannot find any good reason why
you would want this for variables) is make the weak symbol
alias a strong symbol, which can be done by adding
__attribute__((alias("target"))) (to the weakly
linked symbol), where target is the strongly linked
symbol. A less useful, but related, feature you can read up on
for yourself is __attribute__((weakref)) and
__attribute__((weakref("target"))).
An interesting feature of weakly linked symbols is that you
don't need them to be linked at all, and until they are, they
have the null address. This means that you in your application
or library (or C runtime implementation where this becomes
particularly useful) can define weakly linked symbols with
the same names (and types) as symbols provided by another
library, and your code can take the address of those functions
or variables and the address against NULL to see
if the library is available. This is something between the
use of weak links described above and using
<dlfcn.h>: the application/library doesn't
actively link the the library but let's the user or (for a
library) application link it in, and you are not providing
your own stub functions, so there is no risk of replacing
the libraries functions, if they happen to be weakly linked,
with stubs.