【gcc/gdb】指令使用_-finline-functions-程序员宅基地

技术标签: c++  Linux  linux  

目录

gcc编译器

 GNU C/C++编译器的选项说明:

g++与gcc

g++与 gcc 的区别?g++能编译.c 文件吗?gcc 能编译.cpp 文件吗?

gcc优化代码的功能

实例:查看gcc优化选项的效果

基本选项——汇编阶段

汇编器 as

基本选项——链接阶段

链接器 ld

链接器选项

链接器使用实例

gdb调试器

gdb调试


gcc编译器

        GCC是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。GCC可以针对多种硬件平台编译出可执行程序,其平均执行效率比一般编译器生成的程序要高20~30%。使用GCC由C语言源代码文件生成可执行文件的过程要经历四个相互关联的步骤:预处理、编译、汇编和链接。

  • 预处理: GCC调用cpp程序进行预处理,分析和处理#include、#define等预处理命令
  • 编译: GCC调用ccl程序进行编译,根据C源代码生成对应的汇编语言源代码
  • 汇编: GCC调用as程序将上步生成的汇编源代码,汇编生成二进制可重定位目标文件
  • 链接: GCC调用ld程序对组成程序的目标文件进行链接,生成可执行程序文件
  • 使用GCC的命令是gcc,最常用的方式如下:
  • #gcc -o filename sample1.c sample2.c sample3.c

        使用[-o filename]参数,可以在c程序编译后,输出可执行的文件名为filename;如果没有这个参数,GCC将使用缺省的可执行文件名a.out

 GNU C/C++编译器的选项说明:

  • -x language       指定语言(C、C++和汇编为有效值)
  • -c                只进行编译和汇编(不链接)
  • -S                编译(不汇编或链接)
  • (-s) file
  • -E                只进行预处理(不编译、汇编或链接)
  • -o file                 用来指定输出文件名
  • -l library                    用来指定链接所用库
  • -L directory       为库文件的搜索指定目录
  • -I directory         为include文件的搜索指定目录
  • -w                       禁止警告消息
  • -pedantic                   严格要求符合ANSI标准     
  • -Wall                  显示附加的警告信息     
  • -g                        产生排错信息(同gdb一起使用时)
  • -ggdb                  产生排错信息(用于gdb) 
  • -p                        产生proff所需的信息   
  • -pg                      产生groff所需的信息
  • -o                        优化
  • 主要处理C语言源文件中的#ifdef、#include以及#define等命令
  • GCC会忽略掉不需要预处理的输入文件,该阶段会生成中间文件*.i
  • 例:对于源程序example.c ,使用如下命令对源文件进行预处理
  •                                gcc -E example.c -o example.i
  • 说明:该例子使用了两个选项:-E和-o,其中-E表示在预处理结束后即停止编译过程;-o指定输出文件。前面的选项不同,输出的文件类型也不相同,可能为预处理后的C代码、汇编文件、目标文件或可执行文件,这里即为预处理后的C代码

g++与gcc

g++与 gcc 的区别?g++能编译.c 文件吗?gcc 能编译.cpp 文件吗?

  • 1) gcc 现在是 GNU 提供的一些编译器工具的集合(Gnu Compiler Collection),以前是GNU 组织提供的 c 编译器(Gnu C Compiler)。 g++是 c++编译器编译器。
  • 2) gcc 可以编译.c 和.cpp 的源文件,对*.c 按 c 语言语法规则处理, *.cpp 自动按 c++语法规则处理,但默认不链接相应的 c++库,需要手动指定链接的库名"-lstdc++"
  • 3) g++可以编译.c 和.cpp 的源文件,但是都按 c++的语法规则来处理。

gcc优化代码的功能

  • gcc具有优化代码的功能,它的优化功能也有多种不同的选项,主要的优化选项如下所示:
  • -O0   不进行优化处理
  • -O或-O1   进行基本的优化,这些优化在大多数情况下都会使程序执行得更快
  • -O2   除了完成-O1级别的优化外,还要一些额外的调整工作,如处理器指令调度等,  这是GNU发布软件的默认优化级别
  • -O3   除了完成-O2级别的优化外,还进行循环的展开以及其它一些与处理器特性相关  的优化工作
  • -Os   生成最小的可执行文件,主要用在嵌入式领域
  • 编译优化选项的选择

  • 一般来讲,优化级别越高,生成的可执行文件的运行速度也越快,但消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,只有到软件发行或开发结束的时候,才考虑对最终生成的代码进行优化。
  • 推荐使用-O2选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点,它是最安全的优化选项。
  • 对于桌面应用,可以尝试-O3选项,在优化时对循环进行了展开,这会使可执行文件增大,速度是否增加取决于特定环境。其实他们之间的速度差异也并不是很明显。
  • -O2选项已经启用绝大多数安全的优化选项,-O3选项是在-O2选项的基础上又增添了一些。其实用户也可以根据需要,在-O2选项的基础自行添加,这样比直接使用-O3选项更加安全。例如增添如下选项:
  • -finline-functions:允许编译器将一些简单的函数在其调用处展开
  • -funswitch-loops:将循环体中值不改变的变量移到循环体之外
  • 实例:查看gcc优化选项的效果

  • 具体的命令格式举例:
  •         gcc -O2 -finline-functions example.c -o example
  • 首先不加任何优化选项,对上面的源程序进行编译:
  •         gcc example.c -o example
  • 使用Linux系统下的time命令来大致统计程序的运行时间:
  •         time ./example
  • time命令的输出结果由三部分组成:
  • real:程序的总执行时间,包括进程的调度、切换等时间;
  • user:用户进程执行的时间;
  • sys:内核执行的时间。
  • 接下来使用优化选项-O2对上面的源程序进行处理:
  •         gcc -O2 example.c -o example
  • 再次统计程序的运行时间,可以看到程序的性能得到大幅度的改善
  •          time ./example
  • 此外,还有一个比较重要的优化选项-march,它表示为特定的CPU类型编译二进制代码,进而取得最佳的优化效果。具体的命令格式为:
  •          gcc --march=<CPU类型> example.c -o example
  • CPU类型如pentium4、pentium4m、pentium-m或athlon64等。

基本选项——汇编阶段

  • 汇编:是将输入的汇编语言文件转换为目标代码,可通过使用-c选项来完成
  •     对应的GCC命令如下例所示:
  •                   gcc -c example.s -o example.o
  •     注意:目标文件虽然是机器代码,但不可执行。
  • 汇编器 as

  • 使用gcc编译程序时,产生汇编代码,as会处理这些汇编代码,从而产生目标文件(二进制文件),而目标文件将生成.o 文件、库或者最终的可执行文件。
  • as 通常情况下是被gcc调用的,但是要使用汇编语言编写程序时,可以手工调用。

基本选项——链接阶段

  • 将生成的目标文件与其它目标文件(或库文件)链接成可执行的二进制代码文件。这一步骤可以使用如下的GCC命令来完成:
  •                     gcc example.o -o example
  • 运行example
  • 如果只需要最终的可执行文件,也可以直接对源文件进行编译链接,对应的GCC命令如下所示:
  •                     gcc example.c -o example
  • 对于一个程序的多个源文件进行编译链接时,可以使用如下格式:
  •                     gcc -o test first.c second.c third.c
  • 该命令将同时编译三个源文件,即first.c、second.c和third.c,然后将它们链接成一个可执行程序,名为test。
  • 注意:生成可执行文件时,被编译和链接的多个源文件中必须有且只能有一个main函数,因为main函数是该程序的入口

链接器 ld

  • 在编写一个较大程序时,经常把它分成许多独立的模块,这时需要链接器把所有的模块组合起来,并结合 C 函数库和初始化代码,产生最后的可执行文件。链接器在产生可执行文件之前,起到重要的作用。
  • 通常情况下,ld被编译器所调用,产生可执行代码,但是如果想更好地控制链接过程,最好手工调用ld。

链接器选项

  • GCC编译器提供的链接器也提供有多个选项:
  • -Idirectory   向GCC的头文件搜索路径中添加新的目录
  • -Ldirectory   向GCC的库文件搜索路径中添加新的目录
  • -llibrary  提示链接程序在创建可执行文件时包含指定的库文件
  • -static    强制使用静态链接库
  • -shared    生成动态库文件
  • 首先区分头文件和库文件这两个基本概念
  • 头文件包含变量和函数的声明,但没有定义函数的实现。例如我们经常用到的头文件stdio.h,其中就包含printf和scanf等格式化输入输出函数的声明,如果在代码中要用到这些函数就需要包含该头文件。
  • 函数的具体实现是在库文件中完成的。库文件可分为静态库和动态库

链接器使用实例

  • 使用GCC直接指定链接程序在创建可执行文件时包含的库文件
  •                       gcc example5.c -o example /usr/lib/i386-linux-gnu/libm.so
  • GCC编译器为链接函数库还提供了一个快捷的选项-l,命令的格式为:
  •                       gcc example5.c -o example5 -lm
  • 它与上面指定库文件的全路径/usr/lib/libm.so命令等价,避免了在命令行写长路径。之所以写为-lm,是因为在Linux下,库文件在命名时遵循一个规范,即以lib开头,因此在用-l选项指定库文件名时可以省去lib,也就是说GCC在对-lm进行处理时,会自动去链接名为libm.so的库文件。
  • GCC编译器在默认情况下使用动态库,但如果使用了-static选项,链接器将忽略动态库,强制使用静态链接库,即使用如下命令:
  •                        gcc example5.c -o example5 -static -lm
  • 此时静态库文件中的代码全部包含到可执行文件中,所以生成的可执行文件比较大。
  • GCC编译器提供了-shared选项来生成动态库文件。
  • 与动态库链接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,且只有在程序执行时函数代码才会被拷贝到内存之中。这样使可执行文件比较小,进而节省了磁盘空间;更重要的是,如果库文件本身被更新了,不需要重新编译与它链接的源程序。

gdb调试器

  •         gdb(GNU Debugger)是由GNU计划完成的、受通用公共许可证(GPL)保护的一个功能强大的交互式程序调试工具,主要工作在字符模式下。gdb不仅可以用来调试C/C++语言编写的程序,还可以用来调试Pascal、Objective-C以及Fortran等语言编写的程序。gdb能在程序运行时观察程序的内部结构和内存的使用情况。gdb主要提供以下功能:
  •  监视程序中变量的值的变化
  •  设置断点,使程序在指定的位置暂停执行,便于检查程序数据和状态
  • 单步执行代码
  •  分析崩溃程序产生的core文件
  • 命令形式:
  •  gdb filename

gdb调试

文章篇幅太长了,就分开写啦~查看该文:GDB调试

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_53830608/article/details/126933150

智能推荐

堆排序-程序员宅基地

文章浏览阅读10w+次,点赞394次,收藏1.1k次。1、首先了解堆是什么堆是一种数据结构,一种叫做完全二叉树的数据结构。2、堆的性质这里我们用到两种堆,其实也算是一种。大顶堆:每个节点的值都大于或者等于它的左右子节点的值。小顶堆:每个节点的值都小于或者等于它的左右子节点的值。如上所示,就是两种堆。如果我们把这种逻辑结构映射到数组中,就是下边这样9 5 8 2 3 4 7 ..._堆排序

压缩numpy数组保存_np保存数组-程序员宅基地

文章浏览阅读235次。原始数组采用npy保存,文件为5409kb。使用npz保存,仅为19kb。_np保存数组

IntelliJ IDEA下载插件超时--解决方法_idea 下载时间超时-程序员宅基地

文章浏览阅读8.6k次,点赞2次,收藏7次。 IntelliJ IDEA下载插件超时--解决方法 方法一:取消使用安全连接方式菜单 -&gt; IntelliJ IDEA -&gt; Preferences -&gt; Apprearance &amp; Behavior -&gt; System Settings 设置 取消 Use secure connection 方法二:在IntelliJ IDEA的插件..._idea 下载时间超时

LUXAND人脸识别(linux版本)_luxand 获取faceid-程序员宅基地

文章浏览阅读1.9k次。https://www.luxand.com/https://www.zhihu.com/question/19561362_luxand 获取faceid

linux系统服务器因为错误操作重启之后无法进入系统_centos系统linux 重启后lvm未激活-程序员宅基地

文章浏览阅读2.3k次。1、挂在光驱,原始的centos镜像2、按F11或者其他提示的按键进入修复模式3、使用以下的命令进行修复;_centos系统linux 重启后lvm未激活

Qt5 利用QProcess执行cmd命令_qt qprocess使用cmd切换目录-程序员宅基地

文章浏览阅读2.6k次。Qt5利用QProcess执行cmd命令把文件从一个目录移动到另一个目录,即执行cmd里的copy命令:copy 原文件 目标位置代码需要在头文件中加入 #include<QProcess>void MainWindow::on_ptn_clicked(){ QProcess p(0); //这个会报错 p.start("copy C:\\Users\..._qt qprocess使用cmd切换目录

随便推点

用Python实现Twilio模块的短信发送_the number is unverified. trial accounts cannot se-程序员宅基地

文章浏览阅读744次。安装Twilio;我在anaconda中使用"conda install twilio"安装失败,但是使用pip可以.并且能够在conda中查到Twilio包;pip install twilio注册Twilio:- 在官网(https://www.twilio.com)点击中间的红色按钮:get free API key进行注册.我使用126.com的邮箱能够成功注册.- 在..._the number is unverified. trial accounts cannot send messages to unverified

PyTorch基础练习-task1_pytorch基础选择题-程序员宅基地

文章浏览阅读1.1k次。PyTorch基础练习-task1一、什么是Pytorch?二、为什么选择Pytorch?三、Python环境配置四、PyTorch安装五、PyTorch基础概念5.1、张量 Tensors一、什么是Pytorch?PyTorch是一个开源深度学习框架,是基于python的一个科学计算包。二、为什么选择Pytorch?2.1、支持python;2.2、动态神经网络;2.3、支持GPU性..._pytorch基础选择题

#小白接口# 使用云函数,人人都能编写和发布自己的API接口_云函数post请求如何写-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏7次。你只需编写简单的云函数,就可以实现自己的业务逻辑,发布后就可以生成自己的接口给客户端调用。果创云支持对云函数进行在线接口编程,进入开放平台我的接口 - 在线接口编程,设计一个新接口,设计和配置好接口参数、接口名称、接口返回后,再把云函数源代码填上,提交审核通过并发布后即可使用。云函数编写入口:在线接口编程。云函数优势云函数具有以下特点和优势:1、无需管理服务器即可运行移动后端代码 2、可在线接口编程,自动生成云接口和接口文档 3、代码简单,功能强大,一行代码就可以实现数据库、短信发送_云函数post请求如何写

八大排序算法的Java实现-程序员宅基地

文章浏览阅读69次。一、插入排序1. 直接插入排序2. 希尔排序

使用Sophus练习李群SO3、SE3以及对应的李代数so3、se3-程序员宅基地

文章浏览阅读2.2k次。这是高博《视觉SLAM14讲,从理论到实践》第4章的练习。加了一些注释和理解:#include <iostream>#include <cmath>using namespace std;#include <Eigen/Core>#include <Eigen/Geometry>#include "sophus/so3.h"#includ..._so3 distance

mat1 and mat2 shapes cannot be multiplied ( )的解决-程序员宅基地

文章浏览阅读8.7w次,点赞36次,收藏70次。问题描述错误代码:class Net(nn.Module): def __init__(self): super(Net, self).__init__() # nn.Conv2d(input_channel, output_channel, kernel, stride) self.conv1 = nn.Conv2d(3,64,5,1,1) # 64个5*5的filter -> 64个124*124的matrix sel_mat1 and mat2 shapes cannot be multiplied