Implementing dynamic initialization for global variables and static member variables in C ++

I have some questions about the implementation of variable initialization in C ++ regarding the process of loading links and the executable module. My main problem is the dynamic initialization of global variables and static member variables, in which the initialization process includes code execution. I am looking for an answer to answer my questions for both Windows and Linux.

I already understand that in the case of static initialization:

- the initial value is placed in its section at compile time

- sections are displayed in memory by the OS module loader

- the variable is assigned the location of the memory address of the initial value using a movement of type DIR32

Here are my questions.

  • What information does the compiler place in the generated object file related to the dynamic initialization of global variables to use the linker? Please tell us as much as possible about related topics and generated characters. What are the differences for static member variables compared to non-statistical global variables?

  • What information does the linker place in the last linked module during the binding process so that the OS module loader can properly initialize all variables (including dynamically initialized global / static member variables that make function calls as part of the initialization)?

  • How does a function that should be executed when a dynamic variable is initialized be mapped to a specific variable that must be initialized with this code?

  • When an executable or dynamically linked module is loaded, how are variables dynamically initialized?

  • Does the implementation of C ++ 11 constant expressions (marked by the constexpr specifier) ​​affect any special considerations compared to the implementation of regular static member variables and functions?

I have a specific example. I hope that the answer can be considered within the framework of the above questions, since I felt that I had a specific example of taking an object file, defining the appropriate sections / characters and how this particular code would be linked and loaded so that successful initialization of the static variable could be performed to make the answer more understandable. This example is for Windows using MSVC as a compiler; state the specific differences for gcc / linux, wherever they exist.

Here is a simple C ++ code example with a regular variable and a static member variable, which from my understanding should be dynamically initialized by the OS loader to main , because it calls a function call as part of its initialization:

class Test { public: static int testFunction() { return 10; } static int memberVar; }; int Test::memberVar = Test::testFunction(); int foo() { return 5; } int var = foo(); int main(int argc, char* argv[]) { var; Test::memberVar; return 0; } 

And here is the section and character dump for the object file created by MSVC using the above code compiled in debug mode (the dump was created using llvm-readobj, a utility that comes with llvm / clang):

 File: Source.obj Format: COFF-i386 Arch: i386 AddressSize: 32bit Sections [ Section { Number: 1 Name: .drectve (2E 64 72 65 63 74 76 65) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 65 PointerToRawData: 0x2BC PointerToRelocations: 0x0 PointerToLineNumbers: 0x0 RelocationCount: 0 LineNumberCount: 0 Characteristics [ (0x100A00) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_LNK_INFO (0x200) IMAGE_SCN_LNK_REMOVE (0x800) ] } Section { Number: 2 Name: .debug$S (2E 64 65 62 75 67 24 53) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 3380 PointerToRawData: 0x2FD PointerToRelocations: 0x1031 PointerToLineNumbers: 0x0 RelocationCount: 8 LineNumberCount: 0 Characteristics [ (0x42100040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 3 Name: .debug$T (2E 64 65 62 75 67 24 54) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 136 PointerToRawData: 0x1081 PointerToRelocations: 0x0 PointerToLineNumbers: 0x0 RelocationCount: 0 LineNumberCount: 0 Characteristics [ (0x42100040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 4 Name: .text$di (2E 74 65 78 74 24 64 69) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 60 PointerToRawData: 0x1109 PointerToRelocations: 0x1145 PointerToLineNumbers: 0x0 RelocationCount: 3 LineNumberCount: 0 Characteristics [ (0x60501020) IMAGE_SCN_ALIGN_16BYTES (0x500000) IMAGE_SCN_CNT_CODE (0x20) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_EXECUTE (0x20000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 5 Name: .debug$S (2E 64 65 62 75 67 24 53) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 216 PointerToRawData: 0x1163 PointerToRelocations: 0x123B PointerToLineNumbers: 0x0 RelocationCount: 5 LineNumberCount: 0 Characteristics [ (0x42101040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 6 Name: .text$di (2E 74 65 78 74 24 64 69) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 60 PointerToRawData: 0x126D PointerToRelocations: 0x12A9 PointerToLineNumbers: 0x0 RelocationCount: 3 LineNumberCount: 0 Characteristics [ (0x60501020) IMAGE_SCN_ALIGN_16BYTES (0x500000) IMAGE_SCN_CNT_CODE (0x20) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_EXECUTE (0x20000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 7 Name: .debug$S (2E 64 65 62 75 67 24 53) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 204 PointerToRawData: 0x12C7 PointerToRelocations: 0x1393 PointerToLineNumbers: 0x0 RelocationCount: 5 LineNumberCount: 0 Characteristics [ (0x42101040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 8 Name: .text$mn (2E 74 65 78 74 24 6D 6E) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 42 PointerToRawData: 0x13C5 PointerToRelocations: 0x0 PointerToLineNumbers: 0x0 RelocationCount: 0 LineNumberCount: 0 Characteristics [ (0x60501020) IMAGE_SCN_ALIGN_16BYTES (0x500000) IMAGE_SCN_CNT_CODE (0x20) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_EXECUTE (0x20000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 9 Name: .debug$S (2E 64 65 62 75 67 24 53) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 192 PointerToRawData: 0x13EF PointerToRelocations: 0x14AF PointerToLineNumbers: 0x0 RelocationCount: 5 LineNumberCount: 0 Characteristics [ (0x42101040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 10 Name: .text$mn (2E 74 65 78 74 24 6D 6E) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 42 PointerToRawData: 0x14E1 PointerToRelocations: 0x0 PointerToLineNumbers: 0x0 RelocationCount: 0 LineNumberCount: 0 Characteristics [ (0x60501020) IMAGE_SCN_ALIGN_16BYTES (0x500000) IMAGE_SCN_CNT_CODE (0x20) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_EXECUTE (0x20000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 11 Name: .debug$S (2E 64 65 62 75 67 24 53) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 204 PointerToRawData: 0x150B PointerToRelocations: 0x15D7 PointerToLineNumbers: 0x0 RelocationCount: 5 LineNumberCount: 0 Characteristics [ (0x42101040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 12 Name: .text$mn (2E 74 65 78 74 24 6D 6E) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 39 PointerToRawData: 0x1609 PointerToRelocations: 0x0 PointerToLineNumbers: 0x0 RelocationCount: 0 LineNumberCount: 0 Characteristics [ (0x60501020) IMAGE_SCN_ALIGN_16BYTES (0x500000) IMAGE_SCN_CNT_CODE (0x20) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_EXECUTE (0x20000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 13 Name: .debug$S (2E 64 65 62 75 67 24 53) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 224 PointerToRawData: 0x1630 PointerToRelocations: 0x1710 PointerToLineNumbers: 0x0 RelocationCount: 5 LineNumberCount: 0 Characteristics [ (0x42101040) IMAGE_SCN_ALIGN_1BYTES (0x100000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_DISCARDABLE (0x2000000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 14 Name: .bss (2E 62 73 73 00 00 00 00) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 8 PointerToRawData: 0x0 PointerToRelocations: 0x0 PointerToLineNumbers: 0x0 RelocationCount: 0 LineNumberCount: 0 Characteristics [ (0xC0300080) IMAGE_SCN_ALIGN_4BYTES (0x300000) IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80) IMAGE_SCN_MEM_READ (0x40000000) IMAGE_SCN_MEM_WRITE (0x80000000) ] } Section { Number: 15 Name: .rtc$IMZ (2E 72 74 63 24 49 4D 5A) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 4 PointerToRawData: 0x1742 PointerToRelocations: 0x1746 PointerToLineNumbers: 0x0 RelocationCount: 1 LineNumberCount: 0 Characteristics [ (0x40301040) IMAGE_SCN_ALIGN_4BYTES (0x300000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 16 Name: .rtc$TMZ (2E 72 74 63 24 54 4D 5A) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 4 PointerToRawData: 0x1750 PointerToRelocations: 0x1754 PointerToLineNumbers: 0x0 RelocationCount: 1 LineNumberCount: 0 Characteristics [ (0x40301040) IMAGE_SCN_ALIGN_4BYTES (0x300000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_LNK_COMDAT (0x1000) IMAGE_SCN_MEM_READ (0x40000000) ] } Section { Number: 17 Name: .CRT$XCU (2E 43 52 54 24 58 43 55) VirtualSize: 0x0 VirtualAddress: 0x0 RawDataSize: 8 PointerToRawData: 0x175E PointerToRelocations: 0x1766 PointerToLineNumbers: 0x0 RelocationCount: 2 LineNumberCount: 0 Characteristics [ (0x40300040) IMAGE_SCN_ALIGN_4BYTES (0x300000) IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) IMAGE_SCN_MEM_READ (0x40000000) ] } ] Symbols [ Symbol { Name: @comp.id Value: 14776701 Section: IMAGE_SYM_ABSOLUTE (-1) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: @feat.00 Value: 2147484049 Section: IMAGE_SYM_ABSOLUTE (-1) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: .drectve Value: 0 Section: .drectve (1) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 65 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } AuxSectionDef { Length: 0 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$S Value: 0 Section: .debug$S (2) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 3380 RelocationCount: 8 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } AuxSectionDef { Length: 112874624 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$T Value: 0 Section: .debug$T (3) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 136 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } AuxSectionDef { Length: 0 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .text$di Value: 0 Section: .text$di (4) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 60 RelocationCount: 3 LineNumberCount: 0 Checksum: 0x46C8586B Number: 0 Selection: Any (0x2) } AuxSectionDef { Length: 2651074843 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$S Value: 0 Section: .debug$S (5) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 216 RelocationCount: 5 LineNumberCount: 0 Checksum: 0x0 Number: 4 Selection: Associative (0x5) AssocSection: .text$di (4) } AuxSectionDef { Length: 726561912 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .text$di Value: 0 Section: .text$di (6) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 60 RelocationCount: 3 LineNumberCount: 0 Checksum: 0x46C8586B Number: 0 Selection: Any (0x2) } AuxSectionDef { Length: 1313174712 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$S Value: 0 Section: .debug$S (7) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 204 RelocationCount: 5 LineNumberCount: 0 Checksum: 0x0 Number: 6 Selection: Associative (0x5) AssocSection: .text$di (6) } AuxSectionDef { Length: 3135640214 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .text$mn Value: 0 Section: .text$mn (8) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 42 RelocationCount: 0 LineNumberCount: 0 Checksum: 0xB9575122 Number: 0 Selection: NoDuplicates (0x1) } AuxSectionDef { Length: 936864182 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$S Value: 0 Section: .debug$S (9) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 192 RelocationCount: 5 LineNumberCount: 0 Checksum: 0x0 Number: 8 Selection: Associative (0x5) AssocSection: .text$mn (8) } AuxSectionDef { Length: 3843792410 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .text$mn Value: 0 Section: .text$mn (10) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 42 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x2AAFA5E4 Number: 0 Selection: Any (0x2) } AuxSectionDef { Length: 919462443 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$S Value: 0 Section: .debug$S (11) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 204 RelocationCount: 5 LineNumberCount: 0 Checksum: 0x0 Number: 10 Selection: Associative (0x5) AssocSection: .text$mn (10) } AuxSectionDef { Length: 1658743834 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .text$mn Value: 0 Section: .text$mn (12) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 39 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x9F9044F9 Number: 0 Selection: NoDuplicates (0x1) } AuxSectionDef { Length: 607079010 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: .debug$S Value: 0 Section: .debug$S (13) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 224 RelocationCount: 5 LineNumberCount: 0 Checksum: 0x0 Number: 12 Selection: Associative (0x5) AssocSection: .text$mn (12) } AuxSectionDef { Length: 3159278302 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: ?testFunction@Test @@SAHXZ Value: 0 Section: .text$mn (10) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: ??__E?memberVar@Test @@ 2HA@ @YAXXZ Value: 0 Section: .text$di (4) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: ?foo@ @YAHXZ Value: 0 Section: .text$mn (8) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: ??__Evar@ @YAXXZ Value: 0 Section: .text$di (6) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: _main Value: 0 Section: .text$mn (12) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: __RTC_CheckEsp Value: 0 Section: IMAGE_SYM_UNDEFINED (0) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: __RTC_InitBase Value: 0 Section: IMAGE_SYM_UNDEFINED (0) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: __RTC_Shutdown Value: 0 Section: IMAGE_SYM_UNDEFINED (0) BaseType: Null (0x0) ComplexType: Function (0x2) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: .bss Value: 0 Section: .bss (14) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 8 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } AuxSectionDef { Length: 0 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: ?memberVar@Test @@2HA Value: 4 Section: .bss (14) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: ?var@ @3HA Value: 0 Section: .bss (14) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: External (0x2) AuxSymbolCount: 0 } Symbol { Name: .rtc$IMZ Value: 0 Section: .rtc$IMZ (15) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 4 RelocationCount: 1 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: Any (0x2) } AuxSectionDef { Length: 1569749662 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: __RTC_InitBase.rtc$IMZ Value: 0 Section: .rtc$IMZ (15) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: .rtc$TMZ Value: 0 Section: .rtc$TMZ (16) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 4 RelocationCount: 1 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: Any (0x2) } AuxSectionDef { Length: 1278087628 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: __RTC_Shutdown.rtc$TMZ Value: 0 Section: .rtc$TMZ (16) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: .CRT$XCU Value: 0 Section: .CRT$XCU (17) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 2 AuxSectionDef { Length: 8 RelocationCount: 2 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } AuxSectionDef { Length: 3724741121 RelocationCount: 0 LineNumberCount: 0 Checksum: 0x0 Number: 0 Selection: 0x0 } } Symbol { Name: ?memberVar$initializer$@Test @@2P6AXXZA Value: 0 Section: .CRT$XCU (17) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 0 } Symbol { Name: _var$initializer$ Value: 4 Section: .CRT$XCU (17) BaseType: Null (0x0) ComplexType: Null (0x0) StorageClass: Static (0x3) AuxSymbolCount: 0 } ] 

Thanks so much for considering my question; A thorough answer would be greatly appreciated.

+7
c ++ initialization static linker
source share
1 answer

This is less of a linker problem than a compiler / runtime problem. Of course, the full answer depends on the system and the system, but for gcc / clang on Linux something like this. Any specific characters or sections that I mentioned relate to ARM, other processors may be different.

I copied your small sample program into the ELLCC demo , which is a clan-based distribution, and compiled it for ARM. I had to turn off optimization to see something interesting, because your initialized variables are not used.

What you will see when looking at the assembler language is that the compiler will generate code for any initialization that must be performed in the source file. As you pointed out, things initialized by link-time constant constants can be initialized by placing the corresponding character and its initial value in a section (usually called .data for written materials and .const for read-only materials.) Values ​​that cannot be calculated at compilation or link time, are initialized by the generated compiler function, which is executed before main () is entered. If you compile your example and look at the assembly, towards the end there are a few lines that look like this:

 .section .init_array,"aw",%init_array .align 2 .long _GLOBAL__sub_I__6873_0.cc(target1) 

The magic here is that the .init_array section is a section with special meaning for the compiler and runtime system. the compiler placed the address of the built-in function in the .init_array section. The function performs any initialization necessary for these source files. If you had C ++ static constructors in the source, they would also be called from here. A similar section for x86 processors is called .ctors, which has similar semantics.

Now comes the runtime part. When a program starts, the runtime system gains control first. It performs functions such as initializing the library, possibly loading dynamic libraries, etc., and each pointer to each function in .init_array and executes it. This results in the initialization of your variables.

Note that the linker really does not need to do anything but collect all the function pointers in .init_array in one place so that the runtime system can finance them.

As you might have guessed, there is another section called .fini_array (or .dtors in the x86 world) that we used when the program tries to exit, global destructors process it.

+1
source share

All Articles