public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Is init_priority file scope or global scope?
@ 2010-12-12  0:47 H.J. Lu
  2010-12-12  7:45 ` Dave Korn
  2010-12-13 19:30 ` Ian Lance Taylor
  0 siblings, 2 replies; 5+ messages in thread
From: H.J. Lu @ 2010-12-12  0:47 UTC (permalink / raw)
  To: GCC Development

Hi,

Using .init_array section on Linux/x86 raised a question on
init_priority.  GCC manual says

`init_priority (PRIORITY)'
     In Standard C++, objects defined at namespace scope are guaranteed
     to be initialized in an order in strict accordance with that of
     their definitions _in a given translation unit_.  No guarantee is
     made for initializations across translation units.  However, GNU
     C++ allows users to control the order of initialization of objects
     defined at namespace scope with the `init_priority' attribute by
     specifying a relative PRIORITY, a constant integral expression
     currently bounded between 101 and 65535 inclusive.  Lower numbers
     indicate a higher priority.

     In the following example, `A' would normally be created before
     `B', but the `init_priority' attribute has reversed that order:

          Some_Class  A  __attribute__ ((init_priority (2000)));
          Some_Class  B  __attribute__ ((init_priority (543)));

     Note that the particular values of PRIORITY do not matter; only
     their relative ordering.

Is init_priority file scope or global scope? I consider init_priority is
file scope.  Is that a correct assumption?

-- 
H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is init_priority file scope or global scope?
       [not found]   ` <AANLkTikKgt8Jm36L4g96v=cNDRwoqkGun_xoyDWorX-W@mail.gmail.com>
@ 2010-12-12  7:40     ` Dave Korn
  2010-12-13 19:41       ` Ian Lance Taylor
  0 siblings, 1 reply; 5+ messages in thread
From: Dave Korn @ 2010-12-12  7:40 UTC (permalink / raw)
  To: H.J. Lu, gcc

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is init_priority file scope or global scope?
  2010-12-12  0:47 Is init_priority file scope or global scope? H.J. Lu
@ 2010-12-12  7:45 ` Dave Korn
       [not found]   ` <AANLkTikKgt8Jm36L4g96v=cNDRwoqkGun_xoyDWorX-W@mail.gmail.com>
  2010-12-13 19:30 ` Ian Lance Taylor
  1 sibling, 1 reply; 5+ messages in thread
From: Dave Korn @ 2010-12-12  7:45 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Development

On 12/12/2010 00:47, H.J. Lu wrote:
> Hi,
> 
> Using .init_array section on Linux/x86 raised a question on
> init_priority.  GCC manual says
> 
> `init_priority (PRIORITY)'
>      In Standard C++, objects defined at namespace scope are guaranteed
>      to be initialized in an order in strict accordance with that of
>      their definitions _in a given translation unit_.  No guarantee is
>      made for initializations across translation units.  However, GNU
>      C++ allows users to control the order of initialization of objects
>      defined at namespace scope with the `init_priority' attribute by
>      specifying a relative PRIORITY, a constant integral expression
>      currently bounded between 101 and 65535 inclusive.  Lower numbers
>      indicate a higher priority.
> 
>      In the following example, `A' would normally be created before
>      `B', but the `init_priority' attribute has reversed that order:
> 
>           Some_Class  A  __attribute__ ((init_priority (2000)));
>           Some_Class  B  __attribute__ ((init_priority (543)));
> 
>      Note that the particular values of PRIORITY do not matter; only
>      their relative ordering.
> 
> Is init_priority file scope or global scope? I consider init_priority is
> file scope.  Is that a correct assumption?
> 

  At least on PE-COFF, it's implemented by appending a numeric string to the
.ctor/.dtor section name for the object's __GLOBAL__[CD] entries and letting
them all get sorted by the linker into numeric order in the final output
.ctors/.dtors table, so it ought to be global.


    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is init_priority file scope or global scope?
  2010-12-12  0:47 Is init_priority file scope or global scope? H.J. Lu
  2010-12-12  7:45 ` Dave Korn
@ 2010-12-13 19:30 ` Ian Lance Taylor
  1 sibling, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2010-12-13 19:30 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Development

"H.J. Lu" <hjl.tools@gmail.com> writes:

> Using .init_array section on Linux/x86 raised a question on
> init_priority.  GCC manual says
>
> `init_priority (PRIORITY)'
>      In Standard C++, objects defined at namespace scope are guaranteed
>      to be initialized in an order in strict accordance with that of
>      their definitions _in a given translation unit_.  No guarantee is
>      made for initializations across translation units.  However, GNU
>      C++ allows users to control the order of initialization of objects
>      defined at namespace scope with the `init_priority' attribute by
>      specifying a relative PRIORITY, a constant integral expression
>      currently bounded between 101 and 65535 inclusive.  Lower numbers
>      indicate a higher priority.
>
>      In the following example, `A' would normally be created before
>      `B', but the `init_priority' attribute has reversed that order:
>
>           Some_Class  A  __attribute__ ((init_priority (2000)));
>           Some_Class  B  __attribute__ ((init_priority (543)));
>
>      Note that the particular values of PRIORITY do not matter; only
>      their relative ordering.
>
> Is init_priority file scope or global scope? I consider init_priority is
> file scope.  Is that a correct assumption?

No.  That would be useless.  init_priority has global scope.  That is
what it was designed for.

The documentation could be more clear, but it is clearly saying "C++
specifies the order in a translation unit, init_priority specifies the
order across translation units."

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is init_priority file scope or global scope?
  2010-12-12  7:40     ` Dave Korn
@ 2010-12-13 19:41       ` Ian Lance Taylor
  0 siblings, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2010-12-13 19:41 UTC (permalink / raw)
  To: Dave Korn; +Cc: H.J. Lu, gcc

Dave Korn <dave.korn.cygwin@gmail.com> writes:

>   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.

Same on ELF (except that on ARM EABI it uses .init_array and does not
subtract from 65535; see arm_elf_asm_cdtor).

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-13 19:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-12  0:47 Is init_priority file scope or global scope? H.J. Lu
2010-12-12  7:45 ` Dave Korn
     [not found]   ` <AANLkTikKgt8Jm36L4g96v=cNDRwoqkGun_xoyDWorX-W@mail.gmail.com>
2010-12-12  7:40     ` Dave Korn
2010-12-13 19:41       ` Ian Lance Taylor
2010-12-13 19:30 ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).