This is what I came to say. Here is a working example that builds an array of function pointers at program initialization time.
https://github.com/kbob/schetoo/blob/master/prim.h#L215
This also works across multiple source files, unlike __COUNTER__.
__attribute__((constructor))