Why would you alphabetically order initializations?
Every complex system I've ever worked on that had a large number of initializations was sensitive to orders.
Languages with module support like Wirth's Modula-2 ensure that if module A uses B, B's initialization will execute before A's. If there is no circular dependency, that order will never be wrong.
The reverse order could work too, but it's a crapshoot then. Module dependency doesn't logically entail initialization order dependency: A's initializations might not require B's initializations to have completed.
If you're initializing by explicit calls in a language that doesn't automate the dependencies, the baseline safest thing to do is to call things in a fixed order that is recorded somewhere in the code: array of function addresses, or just an init procedure that calls others directly.
If you sort the init calls, it has to be on some property linked to dependency order, otherwise don't do it. Unless you've encoded something related to dependencies into the module names, lexicographic order is not right.
In the firmware application I work on now, all modules have a statically allocated signature word that is initially zero and set to a pattern when the module is initialized. The external API functions all assert that the pattern has the correct value, which is strong evidence that the module had been initialized before use.
One one occasion I debugged a static array overrun which trashed these signatures, causing the affected modules to assert.
Having a consistent ordering avoids differences in results from inconsistent ordering by construction. IIUC, Alpha sort was/is used as a tie breaker after declared dependencies or other ordering information.
In this case, two (or more) modules indicate they can handle the same hardware and didn't have information on priority if both were present. Probably this should be detected / raise a fault, but under the previous regime of alpha sort, it was handled nicely because the preferred drivers happened to sort first.
A topological sort of the dependency graph is just as consistent as any other sort, so long as you have a deterministic tie breaking mechanism for the case of multiple valid toposorts (which can just be another sort based on some unique property).
Every complex system I've ever worked on that had a large number of initializations was sensitive to orders.
Languages with module support like Wirth's Modula-2 ensure that if module A uses B, B's initialization will execute before A's. If there is no circular dependency, that order will never be wrong.
The reverse order could work too, but it's a crapshoot then. Module dependency doesn't logically entail initialization order dependency: A's initializations might not require B's initializations to have completed.
If you're initializing by explicit calls in a language that doesn't automate the dependencies, the baseline safest thing to do is to call things in a fixed order that is recorded somewhere in the code: array of function addresses, or just an init procedure that calls others directly.
If you sort the init calls, it has to be on some property linked to dependency order, otherwise don't do it. Unless you've encoded something related to dependencies into the module names, lexicographic order is not right.
In the firmware application I work on now, all modules have a statically allocated signature word that is initially zero and set to a pattern when the module is initialized. The external API functions all assert that the pattern has the correct value, which is strong evidence that the module had been initialized before use.
One one occasion I debugged a static array overrun which trashed these signatures, causing the affected modules to assert.