当前位置: 首页 > news >正文

GCC编译器使用

一、GCC简介

通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还含其他相关工具, 所以它能把易于人类使用的高级语言编写的源代码构建成计算机能够直接执行的二进制代码。GCC是Linux平台下最常用的编译程序,它是Linux平台编 译器的事实标准。同时,在Linux平台下的嵌入式开发领域,GCC也是用得最普遍的一种编译器。GCC之所以被广泛采用,是因为它能支持各种不同的目标体系结构。例如,它既支持基于宿主的开发(简单讲就是要为某平台编译程序,就在该平台上编译),也支持交叉编译(即在A平台上编译的程序是供平台B使用的)。目前,GCC支持的体系结构有四十余种,常见的有X86系列、Arm、PowerPC等。同时,GCC还能运行在不同的操作系统上,如Linux、Solaris、Windows等。

除了上面讲的之外,GCC除了支持C语言,还支持多种其他语言,例如C++、Ada、Java、Objective-C、FORTRAN、Pascal、go等。

GCC的安装:

Ubuntu等基于Debian发行版Linux可以使用如下命令安装:

apt -get install gcc

Fedora等基于RPM发行版Linux可以使用如下命令安装:

yum install gcc

使用如下命令查看gcc的版本:

gcc --version

本文地址:http://www.cnblogs.com/archimedes/p/linux-gcc.html,转载请注明源地址。

二、程序的编译过程

对于GUN编译器来说,程序的编译要经历预处理、编译、汇编、连接四个阶段,如下图所示:

从功能上分,预处理、编译、汇编是三个不同的阶段,但GCC的实际操作上,它可以把这三个步骤合并为一个步骤来执行。下面以C语言为例来谈一下不同阶段的输入和输出情况。

GCC编译器的基本选项如下表:

类型说明
-E预处理后即停止,不进行编译、汇编及连接
-S编译后即停止,不进行汇编及连接
-c编译或汇编源文件,但不进行连接
-o file指定输出文件file

在预处理阶段,输入的是C语言的源文件,通常为*.c。它们通常带有.h之类头文件的包含文件。这个阶段主要处理源文件中的#ifdef、 #include和#define命令。该阶段会生成一个中间文件*.i,但实际工作中通常不用专门生成这种文件,因为基本上用不到;若非要生成这种文件 不可,可以利用下面的示例命令:

gcc -E  test.c -o test.i

在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*.s 。这个阶段对应的GCC命令如下所示:

gcc -S test.i -o test.s

在汇编阶段,将输入的汇编文件*.s转换成机器语言*.o。这个阶段对应的GCC命令如下所示:

gcc -c test.s -o test.o

最后,在连接阶段将输入的机器代码文件*.s(与其它的机器代码文件和库文件)汇集成一个可执行的二进制代码文件。这一步骤,可以利用下面的示例命令完成:

gcc test.o -o test

运行如下:

可以通过:cat -n [filename]命令查看每一个阶段的文件内容

上面介绍了GCC编译过程的四个阶段以及相应的命令。下面我们进一步介绍常用的GCC的模式。

三、警告选项

GCC提供了大量的警告选项,对代码中可能存在的问题提出警告,通常可以使用-Wall来开启以下警告

GCC的编译器警告选项如下表:

类型说明
-Wall启用所有警告信息
-Werror在发生警告时取消编译操作,即将警告看作是错误
-w禁用所有警告信息

实例1:给出一段代码,使用gcc进行编译,同时开启警告信息(test1.c)

#include<stdio.h>
int main()
{
   int i;
   for(i = 0; i <= 3; i++)
     printf("hello gcc!\n");
   //return 0;
}

使用-Wall开启警告:

从上面可以看出,GCC给出了警告信息,意思是main函数的返回值被声明为int,但是没有返回值,GCC并不是简单的发出警告,会中断整个编译过程

如果不想看到警告信息,可以使用-w来禁止所有的警告。

此外,GCC还提供了许多以-W开头的选项,允许用户指定输出某个特定的警告,例如:

  • -Wcomment:出现注释嵌套时发出警告。

  • -Wconversion:如果程序中存在隐式类型转换,则发出警告。

  • -Wformat:检查printf和scanf等格式化输入输出函数的格式字符串和参数类型的匹配情况,如果发现不匹配则发出警告。

  • -Winline:如果函数不能被内联,则发出警告。

  • -Wlong-long:如果使用了long long型数据,则发出警告。

  • -Wmain:如果main函数的返回类型不是int型,或者调用main函数时使用的参数数目不正确,则发出警告。

  • -Wmissing-declarations:如果定义了全局函数,但却没有在头文件中声明,则发出警告。

  • -Wparentheses:在某些情况下,如果忽略掉了括号,则会发出警告。

  • -Wreturn-type:如果函数定义了返回类型,而默认类型是int型,编译器会发出警告。

  • -Wuninitialized:如果使用的自动变量没有被初始化,则发出警告。

  • -Wundef:如果在#if宏中使用了未定义的变量做判断,则发出警告。

  • -Wunused:如果声明的变量或static型函数没有使用,则发出警告。

实例2:给出一段代码,使用gcc进行编译,同时开启警告信息(test2.c)

#include<stdio.h>
int main( )
{
    int a = 1;
    int b = 0;
    int c = 1;
    if(a && b || c)
    {
        ;
    }
    if(a == 1)
        if(b == 1)
            printf("b = 1\n");
    else
        printf("b != 1\n");
    return 0;
}

使用-Wparentheses开启警告:

四、优化选项

GCC具有优化代码的功能,主要的优化选项包括如下:

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

一般来说,优化级别越高,生成可执行文件的运行速度也越快,但消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,到软件发行或开发结束的时候才考虑对最终生成的代码进行优化。

  • -finline-functions:允许编译器将一些简单的函数在其调用处展开。
  • -funswitch-loops:将循环体中值不改变的变量移到循环体外。

实例:给出一段代码,使用gcc进行编译,同时比较优化前后执行程序所花的时间(test3.c)

#include<stdio.h>
int main()
{
   int i, j, x;
   x = 0;
   for(i = 0; i < 100000; i++) {
       for(j = i; j > 0; j--) {
           x += j;
       }
   }
   return 0;
}

运行后的结果如下:

可以看到,优化的效果十分的显著

相关文章:

  • EHcache经典配置
  • 基于 lua-resty-upload 实现简单的文件上传服务
  • 面试题系列一之 程序生命周期
  • Linux常用网络命令
  • 静态long类型常量serialVersionUID的作用
  • 用百度输入法的用户体验
  • 代码写累了就画点注释陶冶情操
  • 深入解析Java中的装箱和拆箱
  • SQL SERVER 表最小行的一个纠结问题
  • 利用Android Lost通过互联网或短信远程控制安卓设备
  • http://blog.csdn.net/huang_xw/article/details/7090173
  • Outlook 2013 在邮件里面点击超链接时弹出“组织策略阻止我们为您完成此操作”...
  • Wordpress简单配置
  • [android] 看博客学习hashCode()和equals()
  • Linux MySQL源码安装缺少ncurses-devel包
  • 【Leetcode】104. 二叉树的最大深度
  • 【Linux系统编程】快速查找errno错误码信息
  • 30天自制操作系统-2
  • Android系统模拟器绘制实现概述
  • CentOS从零开始部署Nodejs项目
  • React-redux的原理以及使用
  • Spark学习笔记之相关记录
  • TypeScript实现数据结构(一)栈,队列,链表
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 大整数乘法-表格法
  • 浮现式设计
  • 探索 JS 中的模块化
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (70min)字节暑假实习二面(已挂)
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)LINQ之路
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .naturalWidth 和naturalHeight属性,
  • .net(C#)中String.Format如何使用
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .NET中使用Protobuffer 实现序列化和反序列化
  • @Data注解的作用
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [Android View] 可绘制形状 (Shape Xml)
  • [Angular] 笔记 18:Angular Router
  • [BZOJ] 1001: [BeiJing2006]狼抓兔子
  • [C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型
  • [CDOJ 1343] 卿学姐失恋了
  • [IE编程] IE8 新增的C++开发接口
  • [IE技巧] 如何让IE 启动的时候不加载任何插件
  • [LeetCode] 596:超过5名学生的课
  • [Lucas定理]【学习笔记】
  • [MySQL]数据库基础