Linkers, Loaders & Object Formats

a weak symbol

Normally if two object files both define a global function or variable with the same name, the linker complains: 'multiple definition'. And if a name is used but never defined anywhere, the linker complains too: 'undefined reference'. A weak symbol relaxes both rules. It is a definition that says, in effect, 'use me only if no stronger one exists' or a reference that says 'I would like this, but it is okay if it is missing'. It is a polite, optional kind of symbol.

There are two faces to this. A weak DEFINITION is a global symbol marked weak: if a strong (ordinary) definition of the same name also exists, the strong one wins and the weak one is silently ignored — no 'multiple definition' error. This lets a library ship a default implementation that a user can override just by defining their own. A weak REFERENCE is a use of a symbol marked weak: if no definition is found at link or load time, the reference is simply left as the address zero (a null pointer) instead of being an error, so you can test 'if (the_symbol)' at runtime to see whether it was provided. In C, you create these with a compiler attribute, for example writing __attribute__((weak)) on a declaration or definition with GCC and Clang.

It matters as the mechanism behind overridable defaults and optional features: a runtime can provide a weak default for a hook function and let the program replace it, and a program can weakly reference a symbol that only exists in newer versions of a library so it still links and runs on older ones. The classic pitfall is silence: because a weak definition is overridden without warning, two libraries each shipping a weak symbol of the same name can produce a result that depends on link order, which is hard to debug. And a weak reference that resolves to null will crash if you call it without first checking it is non-null.

// In a library: a weak default the user may override. __attribute__((weak)) void on_startup(void) { /* do nothing */ } // A weak reference: safe to test before use. extern void optional_hook(void) __attribute__((weak)); if (optional_hook) optional_hook(); // skipped if unresolved

A weak definition yields to any strong one without error; a weak reference resolves to null if missing, so you guard the call with a check.

Calling an unresolved weak reference (a null pointer) is a crash, not a no-op — always test it first. And because override happens silently, relying on weak symbols across libraries makes behavior depend on link order.

Also called
weak bindingSTB_WEAK弱繫結