在C ++中实现全局变量和静态成员变量的动态初始化

时间:2015-06-30 11:40:20

标签: c++ static linker initialization

关于链接和可执行模块加载过程,我对C ++中变量初始化的实现有一些疑问。我主要关心的是全局变量和静态成员变量的动态初始化,其中初始化过程涉及代码的执行。我正在寻找解决Windows和Linux问题的答案。

我已经明白,在静态初始化的情况下:

- 在编译期间将初始值放入其自己的部分

- 这些部分由OS模块加载器

映射到内存中

- 通过应用DIR32类型重定位为变量分配初始值的存储器地址的位置

以下是我的问题。

  1. 编译器将哪些信息放入生成的目标文件中,该文件与链接器使用的全局变量的动态初始化有关?请尽可能详细地了解相关部分和生成的符号。与非静态全局变量相比,静态成员变量有什么不同?

  2. 链接器在链接过程中将哪些信息放入最终链接模块中,以便OS模块加载器能够正确初始化所有变量(包括动态初始化的全局/静态成员变量,这些变量将函数调用作为一部分初始化)?

  3. 在动态变量初始化期间需要执行的函数如何映射到需要使用该代码初始化的特定变量?

  4. 加载可执行文件或动态链接模块时,如何执行变量的动态初始化?

  5. 与常规静态成员变量和函数的实现相比,C ++ 11常量表达式(由constexpr说明符标记)的实现是否涉及任何特殊注意事项?

  6. 我有一个具体的例子我希望答案可以在上述问题的框架内提及,因为我觉得有一个具体的例子来获取一个目标文件,识别相关的部分/符号以及如何这个特定的代码将被链接和加载,以便可以执行静态变量的成功初始化将使得答案更容易理解。此示例适用于使用MSVC作为编译器的Windows;请提及gcc / linux的具体差异,无论它们存在于何处。

    这是一个简单的C ++代码示例,涉及常规变量和静态成员变量,根据我的理解,需要在 main 之前由OS加载程序动态初始化,因为它调用了一个函数作为初始化的一部分:

    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使用在调试模式下编译的上述代码生成的目标文件的部分和符号的转储(转储是使用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
      }
    ]
    

    非常感谢您考虑我的问题;非常感谢一个彻底的答案。

1 个答案:

答案 0 :(得分:1)

这不是编译器/运行时问题的链接器问题。完整的答案因系统而异,但对于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)的部分,我们在程序尝试退出时使用它来处理全局析构函数。