gcc/g++/c++ 的各种选项它们几个的使用方式都是一样的,所以我们就以gcc为例来讲

一、gcc 常用的 E/S/c/g 选项

1. -E

只得到.i的扩展C源文件

演示

gcc -E helloworld.c -o helloworld.i

gcc会自动调用cpp或者cc1来进行预处理,如果不写目标文件,就直接输出到控制台

选项调换位置也可以

gcc -o helloworld.i -E helloworld.c

2. -S

只编译到.s文件

演示

gcc -S helloworld.i -o helloworld.s

gcc会自动调用cc1,将.i文件编译为.s文件,如果不写目标文件,会自动保存为同名的.s文件


3. -c

只编译得到.o文件

演示1:

gcc -c helloworld.s -o helloworld.o

自动调用as进行汇编,将.s中的汇编源码翻译为机器指令,并保存到.o文件中

演示2:

gcc -c helloworld.i -o helloworld.o

调用cc1编译得到临时.s文件,调用as.s文件汇编得到.o文件

演示3:

gcc -c helloworld.c -o helloworld.o

调用cc1预编译、编译得到临时的.s文件,调用as.s文件汇编得到.o文件
如果不写目标文件,会自动的保存为同名的.o文件

直接得到可执行文件
演示:

gcc helloworld.c **.c -o helloworld.exe
gcc helloworld.i **.i -o helloworld.exe
gcc helloworld.s **.s -o helloworld.exe
gcc helloworld.o **.o -o helloworld.exe

4. -g

如果要进行debug调试的话,通过指定-g选项,会加入调试信息,没有调试信息是无法进行调试的
debug调试:后面的课程再介绍


二、其它不常用选项

1. 优化级别

O0/O1/O2/Os/O3: 指定优化级别,O0< O1 < O2 < Os < O3

gcc hellowolrd.c -o helloworld.exe -O3

如果不指定有优化级别的话,默认就是O1级别,有关优化的更多情况,后面章节再介绍


2. -Wall 显示警告信息

gcc hellowolrd.c -o helloworld -Wall

表示编译时将所有的警告信息都显示出来,如果不指定的话,默认只显示重要的警告,不重要的警告就不显示

比如,有一个变量定义了但是没有使用,就是一个不重要的警告,
如果指定了-Wall选项,会警告你没有使用,否则不提示这个警告

初学c的时候,老师会告诉你警告没关系,但是在实际开发中警告是不能有的,为什么?

对于程序的警告来说,虽然不是“编译链接”严重错误,但是在程序的运行过程中,
这些警告可能会演变为威胁程序正常运行的错误,所以警告是程序的隐患,
因此在实际开发中,编译时必须将警告排除。


3. -s 对可执行文件进行瘦身

gcc hellowolrd.c -o helloworld -s

不指定-s时,可执行文件都会包含调试等信息,用以实现程序的调试,但是当程序被调试没有bug后发布时,
发布的程序就不再需要这些信息了,指定-s选项后,gcc编译时会对可执行文件进行瘦身,以去掉这些信息


4. -std 指定编译遵守的语言标准

指定编译时遵守的语言标准,C的标准目前有c89、c90、c99、c11

gcc helloworld.c -o helloworld -std=c11 # 编译时,按照 c11 标准来解析C语法格式

如果gcc时指定某个C标准的话,就会使用该标准来编译,
如果不指定的话,就使用gcc默认设置的标准来编译

不过一般来说我们不用关心标准问题,因为我们使用的都是最常见C语法特性,
不管哪个标准都是支持的,所以不用指定特定的标准,gcc设置的默认标准就支持


5. -v 显示编译过程的详细信息

演示:

gcc helloworld.c -o helloworld -v # 显示预处理、编译、汇编、链接,所有过程的详细信息

我怎么知道编译时使用的是as、cc1、collect2、ld这些程序的?
通过加 -v 选项,阅读编译过程的详细信息知道的,后面会分析这些详细信息

疑问:单个过程可以加-v吗?可以,显示的就是单个过程的详细信息,比如

gcc -E helloworld.c -o helloworld.i -v #只显示预处理的详细信息