Linker and Libraries Guide

Weak Symbols

Weak symbol references that are not bound during a link-edit do not result in a fatal error condition, no matter what output file type is being generated.

If a static executable is being generated, the symbol is converted to an absolute symbol and assigned a value of zero.

If a dynamic executable or shared object is being produced, the symbol will be left as an undefined weak reference and assigned the value zero. During process execution, the runtime linker searches for this symbol. If the runtime linker does not find a match, it binds the reference to an address of zero instead of generating a fatal runtime relocation error.

Historically, these undefined weak referenced symbols have been employed as a mechanism to test for the existence of functionality. For example, the following C code fragment might have been used in the shared object libfoo.so.1:


#pragma weak    foo

extern  void    foo(char *);

void bar(char * path)
{
        void (* fptr)(char *);

        if ((fptr = foo) != 0)
                (* fptr)(path);
}

When an application is built that references libfoo.so.1, the link-edit will complete successfully regardless of whether a definition for the symbol foo is found. If during execution of the application the function address tests nonzero, the function is called. However, if the symbol definition is not found, the function address tests zero and so it is not called.

Compilation systems view this address comparison technique as having undefined semantics, which can result in the test statement being removed under optimization. In addition, the runtime symbol binding mechanism places other restrictions on the use of this technique, which prevents a consistent model from being available for all dynamic objects.


Note -

Undefined weak references in this manner are discouraged. Instead, you should use dlsym(3DL) with the RTLD_DEFAULT flag as a means of testing for a symbol's existence. See "Testing for Functionality".