在C ++中对全局变量和静态成员变量进行动态初始化的实现 [英] Implementation of dynamic initialization for global variables and static member variables in C++

查看:86
本文介绍了在C ++中对全局变量和静态成员变量进行动态初始化的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

-这些部分由OS模块加载器映射到内存中

-the sections are mapped into memory by the OS module loader

-使用DIR32类型重定位为变量分配了初始值的内存地址的位置

-the variable is assigned the location of the initial value's memory address with the application of a DIR32 type relocation

这是我的问题.

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

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

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

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?

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

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?

我有一个特定的示例案例,我希望答案可以在上述问题的框架内提及,因为我觉得有一个获取目标文件,识别相关节/符号以及具体方式的具体示例.代码将被链接并加载,以便可以成功完成静态变量的初始化,从而使答案更易于理解.此示例适用于使用MSVC作为编译器的Windows.请提及gcc/linux在任何地方存在的特定差异.

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.

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

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;
}

这是MSVC使用上面在调试模式下编译的代码生成的目标文件的节和符号的转储(转储是使用llvm/clang附带的实用程序llvm-readobj创建的):

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.

推荐答案

这不是链接程序问题,而是编译器/运行时问题.完整的答案当然会因系统而异,但是对于Linux上的gcc/clang来说,是这样的.我要提到的任何特定符号或部分都是针对ARM的,其他处理器可能有所不同.

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.

我将您的小示例程序复制到 ELLCC演示中,它是基于clang的发行版,并将其编译为ARM.我必须关闭优化才能看到任何有趣的东西,因为未使用您初始化的变量.

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.

通过查看汇编语言,您将看到编译器将生成代码以执行需要在源文件中进行的任何初始化.正如您所指出的,可以通过将适当的符号及其初始值放在一个节中来初始化初始化为链接时常数值的事物(对于可写事物,通常将其称为.data;对于只读事物将其称为.const).由编译器生成的函数在输入main()之前执行该函数,以在编译或链接时进行计算.如果您编译示例并查看程序集,则在结尾附近会有几行如下所示:

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)

这里的神奇之处在于,.init_array部分是对编译器和运行时系统具有特殊含义的部分.编译器已将内部生成的函数的地址放在.init_array节中.该函数执行此源文件所需的任何初始化.如果您在源代码中有静态C ++构造函数,也可以从此处调用它们. x86处理器的类似部分称为.ctors,具有相似的语义.

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.

现在是运行时部分.程序启动时,运行时系统将首先获得控制权.它执行诸如初始化库,加载动态库等操作,并使用.init_array中的每个函数指针并执行它.这将初始化您的变量.

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.

请注意,链接器实际上不需要做任何事情,只是将所有函数指针集中在.init_array中,以便运行时系统可以为它们提供资金.

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.

您到现在可能已经猜到了,在程序尝试退出时,我们还使用了另一个名为.fini_array(或x86世界中的.dtors)的节来处理全局析构函数.

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.

这篇关于在C ++中对全局变量和静态成员变量进行动态初始化的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆