关于链接和可执行模块加载过程,我对 C++ 中变量初始化的实现有一些疑问。我主要关心的是全局变量和静态成员变量的动态初始化,其中初始化过程涉及代码的执行。我正在寻找解决我的 Windows 和 Linux 问题的答案。
我已经明白了在静态初始化的情况下:
-初始值在编译时被放入它自己的段
-这些部分被操作系统模块加载器映射到内存中
-应用DIR32类型重定位,变量被分配初始值内存地址的位置
这是我的问题。
编译器将哪些信息放入生成的与全局变量动态初始化相关的目标文件中以供链接器使用?请尽可能详细地了解相关部分和生成的符号。静态成员变量与非静态全局变量相比有什么区别?
链接器在链接过程中将哪些信息放入最终链接模块,以便操作系统模块加载器能够正确初始化所有变量(包括动态初始化的全局/静态成员变量,这些变量将调用函数作为一部分初始化)?
动态变量初始化期间需要执行的函数如何映射到需要用该代码初始化的特定变量?
加载可执行文件或动态链接模块时,如何执行变量的动态初始化?
与常规静态成员变量和函数的实现相比,C++11 常量表达式(由 constexpr 说明符标记)的实现是否涉及任何特殊注意事项?
我有一个具体的示例案例,我希望答案可以在上述问题的框架内引用,因为我觉得有一个获取目标文件的具体示例,识别相关的部分/符号以及这个特定的代码将被链接和加载,以便可以执行静态变量的成功初始化将使答案更容易理解。此示例适用于使用 MSVC 作为编译器的 Windows;请提及 gcc/linux 存在的具体差异。
这是一个简单的 C++ 代码示例,涉及一个常规变量和一个静态成员变量,根据我的理解,它需要在 main 之前由操作系统加载器动态初始化,因为它调用了一个函数作为其初始化的一部分:
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;
}
这里是 MSVC 使用上述在 Debug模式下编译的代码生成的目标文件的部分和符号的转储(转储是使用 llvm-readobj 创建的,这是一个 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
}
]
非常感谢您考虑我的问题;一个彻底的答案将不胜感激。
最佳答案
这与其说是链接器问题,不如说是编译器/运行时问题。完整的答案当然因系统而异,但对于 Linux 上的 gcc/clang 来说是这样的。我提到的任何特定符号或部分都是针对 ARM 的,其他处理器可能有所不同。
我将您的小示例程序复制到 ELLCC demo 中,这是一个基于 clang 的发行版,并为 ARM 编译了它。我不得不关闭优化以查看任何有趣的内容,因为未使用您的初始化变量。
通过查看汇编语言,您将看到编译器将生成代码来执行需要在源文件中完成的任何初始化。正如您所指出的,可以通过将适当的符号及其初始值放在一个部分中来初始化初始化为链接时间常量值的事物(对于可写内容通常称为 .data,对于只读内容通常称为 .const。)不能的值在编译或链接时计算由编译器生成的函数初始化,该函数在进入 main() 之前执行。如果您编译您的示例并查看程序集,接近尾声时有几行看起来像这样:
.section .init_array,"aw",%init_array
.align 2
.long _GLOBAL__sub_I__6873_0.cc(target1)
这里的神奇之处在于 .init_array 部分是对编译器和运行时系统具有特殊意义的部分。编译器已将内部生成的函数的地址放在 .init_array 部分中。该函数执行此源文件所需的任何初始化。如果源代码中有静态 C++ 构造函数,它们也会从此处调用。 x86 处理器有一个类似的部分,称为 .ctors,它具有类似的语义。
现在是运行时部分。当程序启动时,运行时系统首先获得控制权。它执行诸如初始化库、加载动态库等操作,然后获取 .init_array 中的每个函数指针并执行它。这会初始化您的变量。
请注意,链接器实际上不需要做任何事情,只是将 .init_array 中的所有函数指针收集到一个地方,以便运行时系统可以为它们提供资金。
您现在可能已经猜到,还有另一个名为 .fini_array(或 x86 世界中的 .dtors)的部分,我们在程序尝试退出时使用它来处理全局析构函数。
关于c++ - C++中全局变量和静态成员变量动态初始化的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31137260/