On 12/12/2010 06:54, H.J. Lu wrote: [ off-list, but it's not personal, so let's Cc the list back in, someone might find this explanation of the mechanism useful in the archives. ]
> Can you check the assembly output? Since > > ---- > Note that the particular values of PRIORITY do not matter; only > their relative ordering. > --- > > on Linux, the numeric string in section name isn't the same as > PRIORITY in source file. That means on Linux, the order > of .ctors sections in 2 files isn't the relative ordering of PRIORITY > of those 2 files. Well, at least on PE-COFF, the numeric string is (65536-priority). It is zero padded to five digits, so that the linker's alphabetical sort effectively becomes a numeric sort, and the reason for the inverting the numeric order of priorities is because .ctors gets read backwards at startup. I did actually check the assembly somewhere between writing "IIRC" and finishing my email as it happens. For a testcase based on your example: class Some_Class { int x; public: Some_Class(); ~Some_Class(); }; Some_Class A __attribute__ ((init_priority (2000))); Some_Class B __attribute__ ((init_priority (543))); ... what we get is a static_initialization_and_destruction function that takes the init priority level as an argument and constructs or destroys (per a second argument) everything at that level only: .file "clas.c" .globl _A .bss .align 4 _A: .space 4 .globl _B .align 4 _B: .space 4 .text .def __Z41__static_initialization_and_destruction_0ii; .scl 3; .type 32; .endef __Z41__static_initialization_and_destruction_0ii: LFB0: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 subl $24, %esp cmpl $1, 8(%ebp) jne L2 cmpl $2000, 12(%ebp) ^^^^^^^^^^^^^^^^^^^^^^^ jne L3 ^^^^^^^^^^ movl $_A, (%esp) call __ZN10Some_ClassC1Ev L3: cmpl $543, 12(%ebp) ^^^^^^^^^^^^^^^^^^^^^^ jne L2 ^^^^^^^^^^ movl $_B, (%esp) call __ZN10Some_ClassC1Ev L2: cmpl $0, 8(%ebp) jne L1 cmpl $543, 12(%ebp) ^^^^^^^^^^^^^^^^^^^^^^ jne L5 ^^^^^^^^^^ movl $_B, (%esp) call __ZN10Some_ClassD1Ev L5: cmpl $2000, 12(%ebp) ^^^^^^^^^^^^^^^^^^^^^^^ jne L1 ^^^^^^^^^^ movl $_A, (%esp) call __ZN10Some_ClassD1Ev L1: leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE0: Then we have __GLOBAL__[I/D] functions for each priority level, which load the appropriate priority and construct/destruct argument and call that: .def __GLOBAL__I.00543_A; .scl 3; .type 32; .endef __GLOBAL__I.00543_A: LFB1: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 subl $24, %esp movl $543, 4(%esp) ^^^^^^^^^^^^^^^^^^^^^ movl $1, (%esp) ^^^^^^^^^^^^^^^^^^ call __Z41__static_initialization_and_destruction_0ii leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE1: .def __GLOBAL__D.00543_A; .scl 3; .type 32; .endef __GLOBAL__D.00543_A: LFB2: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 subl $24, %esp movl $543, 4(%esp) ^^^^^^^^^^^^^^^^^^^^^ movl $0, (%esp) ^^^^^^^^^^^^^^^^^^ call __Z41__static_initialization_and_destruction_0ii leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE2: .def __GLOBAL__I.02000_A; .scl 3; .type 32; .endef __GLOBAL__I.02000_A: LFB3: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 subl $24, %esp movl $2000, 4(%esp) ^^^^^^^^^^^^^^^^^^^^^^ movl $1, (%esp) ^^^^^^^^^^^^^^^^^^ call __Z41__static_initialization_and_destruction_0ii leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE3: .def __GLOBAL__D.02000_A; .scl 3; .type 32; .endef __GLOBAL__D.02000_A: LFB4: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 subl $24, %esp movl $2000, 4(%esp) ^^^^^^^^^^^^^^^^^^^^^^ movl $0, (%esp) ^^^^^^^^^^^^^^^^^^ call __Z41__static_initialization_and_destruction_0ii leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE4: ... and it is these routines that are inserted in reverse-priority order into the .ctors and .dtors tables (don't forget that the .ctors table is run backward, the .dtors is run forward): .section .ctors.64992,"w" .align 4 .long __GLOBAL__I.00543_A .text .section .dtors.64992,"w" .align 4 .long __GLOBAL__D.00543_A .text .section .ctors.63535,"w" .align 4 .long __GLOBAL__I.02000_A .text .section .dtors.63535,"w" .align 4 .long __GLOBAL__D.02000_A So that ought to be entirely global ordering at final-link time. I don't know if ELF does it differently. cheers, DaveK