> It is important to note that, in the Itanium ABI, even if the module doesn’t currently have
> anything that needs static initialization, the translation unit importing that module will still
> generate the code to call the initializer, because we don’t want the addition of a static initializer
> to a shared object to result in an ABI break
this is false.
Interesting. That is the current implementation in clang, IIUC.
We probably need to clarify that point, because it is indeed problematic if adding a new static initializer means an ABI breakage for the library.
This would be the proposed
It's not clear to me why calling this initializer would be necessary for a shared object anyway, since loading the shared object will run its initialization before that of the executable.
I think this was intended to make the <iostream> __ioinit trick work in a modules world; with that trick, any TU that included the file got a static initializer that runs before anything else. So similarly, if you import an interface unit with a static initializer, you need to run it first. But if the interface unit doesn't have any dynamic initialization, which I would expect to be by far the majority of MIUs, forcing all importers to call an empty function seems like an undesirable pessimization to startup.
The ABI break is not on adding a static initializer to a shared object; it's on adding a static initializer to a module interface unit that isn't in a shared object, and even then you only lose the order of initialization guarantee (unless you use attribute init_priority). This seems acceptable to me.
Jason