How is the order of statics across translation units unspecified then? Does the standard provide one or more standard orders?
Yes, the standard does provide one or more possible orderings. The options available to the implementation are all of the ordering permutations of the translation units. Initializing all the statics of A.obj before B.obj is just as valid as doing B.obj before A.obj. The standard guarantees that they're all linked together and their statics will be initialized in some order. How that order is determined is not specified by the standard and each implementation is free to order them however it wants, even differently between successive runs.
If the implementation were expected to order TU initialization in a self-consistent manner then the behavior would be implementation-defined instead of unspecified. This is not a requirement the standard wanted to place on implementations. The implementation may not even be in control of the choice such as in a multi-threaded linker (so the statics initialized first are dependent on whichever translation unit's worker thread happened to be scheduled by the OS to run first). If the standard wanted to place restrictions on the implementation so that you the user could predict the initialization order on every conforming implementation (even if it differed between implementations), the standard would have made this behavior implementation-defined and whole classes of possible compilation optimizations would be illegal.
If the behavior were undefined behavior then that would mean that the TUs' static objects may be initialized in some order clearly documented by the implementation, or the implementation can elect to initialize only some of them and not document how it makes that choice, or all of them may be left uninitialized, or they all might be initialized to the same value as one of them, or the implementation may raise an error and abort upon seeing any static initializations, or the implementation could happily generate code that causes a CPU exception. Every implementation could do something different and none of them would be considered buggy in terms of standards compliance. Undefined behavior has a beneficial purpose in places but certainly not for static initialization ordering.
Edited by SeanMiddleditch, 06 February 2014 - 05:23 PM.