2026-09-09
Stack Overflow: View Question
Tags: c++, dependency-injection, linker, best-practices
Score: 0 | Views: 147
The asker is coming from Java's Dagger2 world, where the DI framework wires up a graph of collaborators at compile time. They want the same in C++: class A emits FooEvents via a FooEventDispatcher, and class B (a FooListener) should register itself with that dispatcher — without A or the dispatcher knowing B exists at compile time, and ideally with zero runtime overhead. The question is whether the linker can do this wiring.
Why it's interesting: most C++ DI answers reach for runtime service locators, static initializers with self-registration tricks (the classic __attribute__((constructor)) + registry pattern), or template metaprogramming. None of those are truly link-time — they defer to program startup or push complexity into headers. A real link-time answer has to lean on linker mechanics that most developers never touch.
Approach — three linker features worth exploring:
__attribute__((weak)) void register_foo_listeners(); with a no-op default. If B.o is linked in, its strong definition wins and wires up the listener. GCC/Clang support this; MSVC has /alternatename.__attribute__((section("foo_listeners")))). The linker gives you __start_foo_listeners and __stop_foo_listeners symbols bracketing the array. The dispatcher iterates that range — zero runtime discovery cost. This is how Linux uses __initcall and how FreeBSD's SYSINIT works.--wrap / /ALTERNATENAME. Not really DI, but useful when you want the linker to substitute one implementation for another (great for tests).Gotchas:
B lives in a .a and nothing references it, its registration section is discarded. Fix: link B's objects directly, use -Wl,--whole-archive, or add an explicit anchor reference.--gc-sections can eliminate "unreferenced" section contents. Mark them KEEP() in a linker script, use used attribute, or -Wl,--no-gc-sections.So the honest answer is: yes, but it's not a general framework, it's a pattern built from weak symbols and linker sets. It gets you the "zero runtime overhead" property Dagger fans want, at the cost of ABI portability and some linker-flag hygiene.
