编译过程

一.编译过程

编译过程是将高级语言(如C、C++等)源代码转换为可执行程序的过程。它通常包括以下几个步骤:

1.预处理(Preprocessing)

  • 预处理是编译过程的第一步,其主要任务是处理源代码文件中的预处理指令。这些指令以#符号开头,用于包含头文件、宏展开、条件编译等。
  • 预处理器(通常是C/C++编译器的一部分)会根据这些指令生成一个经过预处理的源代码文件,通常以.i.ii为扩展名。

2.编译(Compilation)

  • 编译是将预处理后的源代码翻译成汇编语言的过程。编译器会对源代码进行词法分析、语法分析和语义分析,生成中间代码(通常是汇编语言)。

3.汇编(Assembly)

  • 汇编是将编译生成的汇编代码转换成机器码的过程。汇编器(assembler)将汇编代码翻译成目标平台的二进制指令。

  • 汇编器生成的输出通常是一个目标文件,通常以 .obj.o或 .elf为扩展名。

4.链接(Linking)

  • 链接是将多个目标文件和库文件合并成一个可执行文件的过程。链接器(linker)负责解析符号引用、解决外部引用,将所有目标文件中的代码和数据结合起来,并生成可执行文件。

  • 在链接过程中,还可以链接系统库和第三方库,以满足程序的依赖关系。

5.优化(Optimization)(可选):

  • 一些编译器在编译过程中提供了优化选项,用于改善程序的性能和/或减小可执行文件的大小。优化可以包括内联函数、死代码删除、循环展开等技术。

6.生成可执行文件(Executable)

  • 最终输出是一个可执行文件,它包含了程序的机器码、数据、元数据等信息。可执行文件通常具有扩展名(例如,.exe.out.app等),可以在适当的操作系统上运行。

在链接过程中,还可能涉及重定位(Relocation)符号解析(Symbol Resolution)地址映射(Address Mapping)库文件的加载和共享等操作。这些是编程和操作系统中关键的概念,它们一起协同工作,以便将程序从源代码编译为可执行文件并在运行时正确执行。下面是对这些操作的简要解释:

  1. 符号解析(Symbol Resolution):在编译过程中,源代码中的变量、函数以及其他符号都需要在编译单元中解析为实际的内存地址或符号名称。这个过程涉及到将符号与其定义关联起来,以便在链接阶段能够正确地找到它们。

  2. 重定位(Relocation):编译器在生成目标文件时,通常会生成一些相对地址(如相对于代码或数据段的偏移量)。重定位是指将这些相对地址调整为绝对地址,以便代码和数据可以正确地在内存中加载和访问。这是链接过程的一个重要步骤。

  3. 地址映射(Address Mapping):一旦重定位完成,操作系统在运行时会将可执行文件加载到内存中。地址映射是指将编译后的代码和数据段映射到适当的内存地址上,以便程序可以在内存中运行。这通常涉及到虚拟内存和分页机制。

  4. 库文件的加载和共享:程序通常依赖于各种库文件(动态链接库或静态库),这些库文件包含了一些通用的功能和代码。链接器会在可执行文件中记录这些库的依赖关系,而加载器在运行时负责将这些库加载到内存中。共享库(动态链接库)可以在多个程序之间共享,从而减少内存占用。

三.结构体对齐

C++中的结构体对齐是指如何按照一定规则在内存中排列结构体的成员,以便提高内存访问效率。字节对齐的目的是为了适应硬件对内存的访问要求,优化数据的读取速度和内存利用率

在C++中,默认情况下,结构体的对齐方式是按照成员的自然对齐原则进行的(也就是根据长度最大的成员对齐)

考虑以下示例:

struct MyStruct {
    char a;
    int b;
    double c;
};

根据默认的对齐规则,可以得到该结构体的布局如下:

|---a---|---padding---|---b---|---c---|

其中,a占用1字节,b占用4字节,c占用8字节,padding表示添加的填充字节,在这里是3个字节,用于保证b按照4字节对齐,使得c可以按照8字节对齐。

c++11以后引入两个关键字 alignas (opens new window)与 alignof (opens new window)。其中 alignof 可以计算出类型的对齐方式,alignas 可以指定结构体的对齐方式。

alignas失效的情况:当设定的大小小于最小元素字节时,自动失效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值