Turned out the macros I overlooked at the end of each file placed the struct defining the command in a special linker section, and the parser init would go and load all the commands from that section.
Interesting to know that this trick already existed in the Linux kernel.
I'm (perhaps perversely) disappointed we aren't using more of the linker's power in many C codebases.
This is the reason why I do not like such tricks. This obviously hurts maintainability and probably portability. Is the tradeoff really worth it? Plain stupid registration is just a single line. KISS.
"Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" –Brian Kernighan
A primary problem with linker magic is that it is usually very non-portable. Hacks you do with macros may be ugly but at least they work everywhere, unless you used a non-standard behavior.
Linker tricks tend to be platform specific, and even more so that other tricks (eg POSIX platforms share a lot of common behavior, but still tend to have quite different linkers).
I overrided malloc() and free() with my own memory tracking functions.
On Windows side it wasn't needed, as VS already provided some APIs for it.
https://msdn.microsoft.com/en-us/library/bb918180.aspx
Another interesting thing is that it relies on the linker ordering names in alphabetical order.
The initialization order is implementation dependent in module/package initialization blocks.
The only guarantee is that the modules being imported run first than the one being executed.
Of course it still won't be deterministic if you load classes in parallel in multiple threads.
For example
class A { static final int x = B.y; static final int y = 1; }
class B { static final int x = A.y; static final int y = 2; }
will not produce any static initializers and will do what you probably wanted because everything can be turned into a class constant and resolved at compile time. However this class A { static final Integer x = B.y; static final Integer y = 1; }
class B { static final Integer x = A.y; static final Integer y = 2; }
will not work the way you might want because there is no order in which the static initializers can be run that will do everything in the correct order.
The linker's job is to combine all the separate pieces in a "section" (special linker term) and write out one section.
Using a special named section lets you create an array using macros, though using it for function pointers is probably safe and using it for other data types might be pretty fragile. http://www.compsoc.man.ac.uk/~moz/kernelnewbies/documents/in...