I have some questions about the implementation of variable initialization in C++ in regards to the linking and executable module loading process. My main concern is with dynamic initialization of global variables and static member variables, wherein the initialization process involves the execution of code. I'm looking for the answer to address my questions for both Windows and Linux.
I already understand that in the case of static initialization:
-the initial value is placed into its own section during compilation
-the sections are mapped into memory by the OS module loader
-the variable is assigned the location of the initial value's memory address with the application of a DIR32 type relocation
Here are my questions.
What information does the compiler place into a generated object file relating to dynamic initialization of global variables for the linker to use? Please go into as much detail as possible about related sections and generated symbols. What differences are there for static member variables compared to non-static global variables?
What information does the linker place into the final linked module during the linking process so that the OS module loader is able to correctly initialize all variables (including dynamically initialized global/static member variables that make calls to functions as part of initialization)?
How is the function that needs to be executed during dynamic variable initialization mapped to the particular variable that needs to be initialized with that code?
When an executable or dynamically linked module is loaded, how is dynamic initialization of variables performed?
Does the implementation of C++11 constant expressions (marked by the constexpr specifier) involve any special considerations compared to the implementation of regular static member variables and functions?
I have a specific example case I'm hoping the answer could refer to within the framework of the above questions, since I felt that having a concrete example of taking an object file, identifying the relevant sections/symbols and how this particular code would be linked and loaded so that successful initialization of the static variable could be carried out would make the answer easier to understand. This example is for Windows using MSVC as the compiler; please mention specific differences for gcc/linux wherever they exist.
Here is a simple example of C++ code involving a regular variable and a static member variable which from my understanding needs to be dynamically initialized by the OS loader before main because it makes a call to a function 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 a dump of the sections and symbols for the object file produced by MSVC using the above code compiled in debug mode (the dump was created with llvm-readobj, a utility which 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
}
]
Thank you very much for considering my question; a thorough answer would be greatly appreciated.
Dynamic initialization of object refers to initializing the objects at run time i.e. the initial value of an object is to be provided during run time. Dynamic initialization can be achieved using constructors and passing parameters values to the constructors.
Static Initialization: Here, the variable is assigned a value in advance. This variable then acts as a constant. Dynamic Initialization: Here, the variable is assigned a value at the run time. The value of this variable can be altered every time the program is being run.
The difference between static initialization and dynamic initialization: A static initialization in java is a particular block that is made to run before the main () method in java whereas dynamic initialization refers to the initiation of the project during the rum time.
Static variables can be declared both inside and outside the main function while the global variables are always declared outside the main function.
This is less a linker problem than a compiler/run-time problem. The complete answer varies from system to system of course, but for gcc/clang on Linux goes something like this. Any specific symbols or sections that I'll mention are for the ARM, other processors may be different.
I copied you little example program into the ELLCC demo, which is a clang based distribution , and compiled it for ARM. I had to turn off optimization to see anything interesting, because your initialized variables aren't used.
What you'll see by looking at the assembly language is that the compiler will generate code to do any initialization that needs to be done in the source file. As you pointed out, things initialized to link-time constant values can be initialized by putting the appropriate symbol and it's initial value in a section (usually called .data for writable stuff and .const for read only stuff.) Values that can't be calculated at compile or link time are initialized by a a compiler generated function that is executed before main() is entered. If you compile your example and look at the assembly, near 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 section .init_array is a section with special meaning to the compiler and run-time system. the compiler has placed the address of an internally generated function in the .init_array section. The function does any initialization that this source files needs. If you had static C++ constructors in the source they'd also be called from here. There is a similar section for x86 processors called .ctors which has similar semantics.
Now comes the run-time part. When the program starts up, the run-time system gets control first. It does things like initialize the library, maybe load dynamic libraries, etc. and the takes each function pointer in the .init_array and executes it. This gets your variables initialized.
Notice that the linker didn't really have to do anything except gather all the function pointers in .init_array in one place so the run-time system could fund them.
As you might be guessing by now, there is also another section called .fini_array (or .dtors in the x86 world) that us used when the program tries to exit do handle global destructors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With