The idea is that anybody who needs to add an initializer
declares a function pointer in the
mydata$g,
mydata$m,
or
mydata$t section.
The linker will collect all of those function pointers from
same-named sections together,
and then sort the sections, so that the final order of
fragments in the mydata section is

mydata$a

firstInitializer

main.obj

mydata$g

DoThisSooner3

file3.obj

unspecifiedorder

DoThisSooner4

file4.obj

mydata$m

Function2

file2.obj

unspecifiedorder

Function1

file1.obj

Function3

file3.obj

mydata$t

DoThisLater2

file2.obj

unspecifiedorder

DoThisLater4

file4.obj

mydata$z

lastInitializer

main.obj

The
Initialize­All­The­Things
function
then walks through all the function pointers
between first­Initializer and
last­Initializer
and calls each one.

The alphabetical ordering rule ensures that the
mydata$a fragment comes first,
so that first­Initializer has the
lowest address.
Next comes
the mydata$g fragments,
which contain the early initializers.
Following that are the
mydata$m fragments,
which are the regular initializers.
Next are the
mydata$t fragments,
which contain the late initializers.
And finally the
mydata$z fragment,
which contains last­Initializer.

Now that we understand the principle behind
section grouping and sorting,
we can look at the gotchas next time.

problem here if we write
const INITIALIZER initializer_fn = fn;
and no reference to address of initializer_fn – compiler not generate variable for initializer_fn
for force generate variable we can use fake local function (unreferenced local function has been removed):