C/C++的编译过程(g++编译过程)


1、宏定义是一种预处理命令吗,预处理命令家族是以’#'开头:#include(文件包含)。

#include是怎么工作的呢?
原封不动的将头文件文件中的代码复制道定义处:

输出待编译源码的命令
g++ -E part1.cpp
g++ -E part1.cpp > output.cpp
g++ -DName main.cpp //编译时定义一个宏
定义符号常量:
#define PI 3.1415926
#define MAX_N 10000
定义傻瓜表达式:

定义代码段:

宏定义功能:

基础的替换,不会做语法检查
可以理解为:让编译器写代码——高级功能

源代码–预处理> 待编译源码————编译>目标————链接>可执行文件

预处理阶段:解决处理命令
连接运算符“##”:
#define CAT(a,b) a##_##b // a_b


前言

对C++的编译过程主要是在Linux环境下的g++编译工具实现的,g++的具体用法根据过程再详细介绍。C/C++编译过程主要有以下几个步骤:

1、源码编写:程序员编写源文件和头文件
2、预编译:进行预编译处理,主要是处理宏操作,最后得到预编译源码 .i
3、编译:将预编译源码翻译汇编源码 .s
4、汇编:将汇编源码生成目标文件 .o
5、链接:最后链接所有目标篇文件生成可执行文件,编译完成


一、预编译

假设我有如下源码,且命名为main.cpp

#include <iostream>
#include <stdio.h>
using namespace std;
#define Mystring "Hello,Worlds!\n"
int main(){
	printf(Mystring);
	return 0;
}

在终端执行如下命令即可实现,源代码的预编译, 注意预编译是不会做语法检查的
g++ -E main.cpp # 将main.cpp 进行预编译,并将预编译后的代码输出
g++ -E main.cpp > main.i # 将main.cpp进行预编译,并将预编译后的代码保存到main.i上

1.1 预处理命令

预编译主要是为了处理预处理命令,那么什么是预处理命令了,预处理命令主要有如下几种:

头文件: #include,头文件是为了将头文件中的内容复制到对应的头文件的位置
宏定义: #define, 宏定义就是做的一个基本的替换
条件编译: #ifdef DEBUG…#endif、#ifndef DEBUG…#endif、#if. state…#elif state…#else…#endif,条件满意表示满足条件这编译代码,否则不编译
一些预编译符: ## 连接符,在宏定义的时候连接两个串


# 二、编译这个部分主要是为了检查语法的错误,若无错则生成汇编语言,并执行下一步
g++ -S main.i # 将main.i编译成汇编,并默认保存为main.s
g++ -S main.cpp # 将main.cpp编程汇编,同样保存到main.s

三、汇编

这一步是为了将每一个C++源码文件都生成一个机器可以识别的目标文件:.o或者.obj。注意可以使用nm命令查看目标文件中的字符信息。具体如下:
g++ -c main.s # 将main.s翻译成目标机器指令,默认名字为main.o
g++ -c main.cpp # 将main.cpp 翻译成目标机器指令,默认名字为main.o

nm -C main.o # 执行这个命令可以查看main.o中的符号信息,每一个函数定义都对应一个逻辑地址和‘T’

四、链接

最后一步的链接就是把所有的目标文件都链接成为一个可执行文件,这一步中会检查所有目标文件中的字符信息是否命名冲突,这些字符信息均是变量名或者函数名。
g++ -o main main.o # 将main.o,以及相关的库目标 链接为可执行文件main
g++ -o main main.cpp # 这一步包含上诉所有的步骤

版权声明:本文为qq_40250056原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。