前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Cpp程序的编译过程

Cpp程序的编译过程

作者头像
yifei_
发布2022-11-14 14:16:17
9860
发布2022-11-14 14:16:17
举报
文章被收录于专栏:yifei的专栏

前言

首先gcc与GCC要区分对待,GCC原名为GNU C Compiler,是一个C编译器的代号,但是后来不断地扩展,开始支持很多语言,GCC也就变成了编译器家族GNU Compiler Collection. 另外GNU的意思是GNU not Unix的递归简写(-_-所以那个G到底是啥意思?),这是一个由Stallman发起的一个操作系统计划,但是最后各种编译器什么的工具都写好了,核心的内核没有开发成功,但最后Linux填补了这个空白.

编译的四个阶段

如果只是在命令行编译一下c或c++程序,直接看后面的命令就可以了,但是了解一下编译的的过程,会加深对gcc的理解.

gccfourstep.jpg
gccfourstep.jpg

(环境:ubuntu 18.04 | 已安装gcc/g++) 1.预处理阶段 .c >>> .i 在这个阶段,编译器先把人方便看的程序处理成编译器方便看的程序.

#define删掉,然后展开所有宏定义

处理那些#include,把包含的那些头文件复制过来.

删掉注释

… 下面这个test.cpp

代码语言:javascript
复制
#include <iostream> 
#include <cstdio> 
#define AA a*a 
 
using namespace std; 
 
int main(){ 
    int a=2; 
    int A=AA;//这里会用宏定义替换掉啊 
    cout<<A<<endl; 
    cout<<"hello world!"<<endl; 
    return 0; 
}

用命令 g++ -E test.cpp -o test.i 处理一下生成tes.i文件 (不加-o,就都会输出到屏幕上,不生成.i文件)

代码语言:javascript
复制
此处省略两万行...
static ios_base::Init __ioinit;
}
\# 2 "test.cpp" 2
\# 1 "/usr/include/c++/7/cstdio" 1 3
\# 39 "/usr/include/c++/7/cstdio" 3
\# 40 "/usr/include/c++/7/cstdio" 3
\# 3 "test.cpp" 2
\# 5 "test.cpp"        //可以看到define,include
using namespace std;  // 什么的都没了,被替换为了上面两万多行

int main(){
 int a=2;
 int A=a*a;//此处宏定义被替换了,注释也没了
 cout<<A<<endl;
 cout<<"hello world!"<<endl;
 return 0;
}

2.编译为汇编代码 .i >>> .s 这一阶段,编译器进行:

  • 语法分析
  • 词法分析
  • 生成汇编代码 通过命令 g++ -S test.i -o test.s 可以生成汇编代码,代码太长,就不粘贴了.

3.生成机器码 .s >>> .o 通过 g++ -c test.s -o test.o 生成目标文件,如果程序只有一个文件,这时候应该就可以执行了.如果有多个.o文件,还得需要下一步链接后再运行. 这一步也可以用GNU自带的汇编器as来将汇编文件生成机器码,命令如下:

代码语言:javascript
复制
as test.s -o test.o

这里可以借助hexdump工具来查看二进制文件

代码语言:javascript
复制
hexdump -C test.o > a.txt
vim a.txt

4.链接.o文件 .o >>> 可执行文件

代码语言:javascript
复制
g++ test.o -o test
./test #然后就可以运行文件了

gcc & g++

这两个都是编译器的名字,一般看名字会感觉gcc用来编译c语言,g++用来编译c++的,但实际上这两个既能编译c语言,又能编译c++,g++可以算是gcc的另一个版本. 当gcc编译c程序时 gcc a.c -o a #这样就生成可执行文件a了 当gcc编译c++程序时 gcc a.cpp -lstdc++ #加个-lstdc++链接上c++的库才行. 当g++编译c程序时,跟gcc用法是一样的,实际上g++在编译c程序是也是直接调用的gcc 当g++编译cpp程序时,看下面一节.

最最常用的命令

无论编译.c还是.cpp,g++都挺方便,一般直接都用g++就可以了. 有时候只是想快速的运行一个c或cpp程序而已,就不用看上面那一坨了…直接用这条命令就够了:

代码语言:javascript
复制
g++ test.cpp -o test  #cpp程序
./test #运行
------------------
g++ test.c op test  #c程序
./test #

其他命令

代码语言:javascript
复制
g++ -c main.c #生成.o文件(.object)
g++ -c main.c -o main.o #生成指定名字的.o文件
g++ main.o #将main.o文件生成a.out文件(.obj >> .out)

常用选项

代码语言:javascript
复制
-E	只运行 C 预编译器。
-S  生成汇编代码
-c	只编译并生成目标文件。
-g	生成调试信息。GNU 调试器可利用该信息。
-IDIRECTORY	指定额外的头文件搜索路径DIRECTORY。
-LDIRECTORY	指定额外的函数库搜索路径DIRECTORY。
-lLIBRARY	连接时搜索指定的函数库LIBRARY。
-o	FILE 生成指定的输出文件。用在生成可执行文件时。
-O0	不进行优化处理。
-O	或 -O1 优化生成代码。
-O2	进一步优化。
-O3	比 -O2 更进一步优化,包括 inline 函数。
-w	不生成任何警告信息。
-Wall	生成所有警告信息。

参考

C语言中文网 GCC编译c语言程序完整演示 c语言真正的编译过程 Linux查看二进制文件内容 GCC

欢迎与我分享你的看法。 转载请注明出处:http://taowusheng.cn/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 编译的四个阶段
  • gcc & g++
  • 最最常用的命令
  • 其他命令
  • 常用选项
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档