阅读本文大概需要 5 分钟。
编译器介绍
首先介绍下GCC,GCC(GNU Compiler Collection)是GUN编译器集合,它可以编译C、C++、JAV、Fortran、Pascal、Object-C等语言
gcc 是GCC中的GUN C Compiler(C 编译器)
g++ 是GCC中的GUN C++ Compiler(C++编译器)
gcc和g++的主要区别:编译和链接阶段有所不同
// g++编译c++
g++ -o main main.cpp
// gcc编译c++
gcc main.cpp -lstdc++ -o main
对于*.c和*.cpp文件,g++则统一当做cpp文件编译;gcc分别当做c和cpp文件编译
使用g++编译文件时,g++会自动链接标准库STL;gcc不会自动链接STL,为了能够使用STL,需要加参数–lstdc++
g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏;gcc在编译C文件时,可使用的预定义宏是比较少的
编译过程
编译是将代码翻译成机器语言的过程:每一个cpp源码文件对应一个编译单元,即每一个cpp源文件会生成一个对应的目标文件(.o结尾),再经过一系列的链接操作,生成最终的应用程序。以hello.cpp文件为例说明整个编译过程。
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
编译过程
g++ -o hello hello.cpp
添加-v可以查看完整编译过程
g++ -o hello hello.c -v
编译过程分为以下几步:
① 预处理阶段 -> ② 编译阶段 -> ③ 汇编阶段 -> ④ 链接阶段
① 预处理阶段
该阶段编译器对源文件做展开处理,包括:
将#include 的头文件展开
将#define语句指定的值转换为变量
将将宏定义转换为具体代码
根据#if #elif和#endif指定的位置包含或排除特定部分的代码
g++ -E main.cpp -o main.i
② 编译阶段
该阶段对展开后的源文件hello.i 进行语法检查,确认代码是否满足语言相关的语法规则,检查通过后生成汇编文件hello.s
g++ -S main.i -o main.s
③ 汇编阶段
该阶段汇编器将汇编文件转换为机器可以执行的指令,生成目标文件hello.o
g++ -c main.s -o main.o
④ 链接阶段
示例hello.cpp文件中调用了printf函数,目标文件hello.o中引用的printf符号还未解析,hello.o还无法正常运行,还需要将系统运行库libc和相关的启动文件(crt文件)链接在一起,才能生成最终可执行的程序hello
g++ main.o -o main
编译标准
-std=c11 Conform to the ISO 2011 C standard
-std=c89 Conform to the ISO 1990 C standard
-std=c90 Conform to the ISO 1990 C standard
-std=c99 Conform to the ISO 1999 C standard
-std=gnu11 Conform to the ISO 2011 C standard with GNU extensions
-std=gnu89 Conform to the ISO 1990 C standard with GNU extensions
-std=gnu90 Conform to the ISO 1990 C standard with GNU extensions
-std=gnu99 Conform to the ISO 1999 C standard with GNU extensions
通过如下命令查看是否支持编译标准:
默认编译标准:
gcc -E -dM - </dev/null | grep __STDC_VERSION__
查看gnu11是否支持:
gcc -std=gnu11 -E -dM - </dev/null | grep __STDC_VERSION__
往期推荐
往期推荐
公众号后台回复「加群」拉你进技术交流群
公众号后台回复「编程」送你编程面试资料