gcc原理和使用

gcc

gcc是什么

GCC,全称 GNU Compiler Collection(GNU 编译器套件),是一套功能强大的编程语言编译器,由自由软件基金会(Free Software Foundation, FSF)作为GNU项目的一部分开发和维护。它最初被创建为一个C语言编译器,后来扩展支持了C++,以及随着时间的推移增加了对其他编程语言的支持,如Fortran、Ada、Java、Go和Rust等。

主要特点与功能

  1. 多语言支持

    • GCC最初是作为C编译器开发的,因此得名GNU C Compiler。
    • 随后增加了对C++(称为G++)、Fortran、Ada等多种语言的支持。
  2. 跨平台编译

    • GCC可以用于多种操作系统平台,包括Linux、Windows、macOS等。
    • 它能够生成跨平台的代码,使得编写的程序能在不同的系统架构上运行。
  3. 优化能力

    • 提供多种级别的优化选项,帮助开发者提升程序的执行效率。
    • 优化选项包括但不限于代码大小优化、执行速度优化等。
  4. 标准遵循与兼容性

    • GCC严格遵循各种编程语言的标准,例如ISO C++和ISO C标准。
    • 不断更新以支持最新的语言标凈。
  5. 调试和错误报告

    • 提供详细的错误和警告信息,帮助开发者快速定位问题。
    • 与GDB(GNU Debugger)等调试工具配合良好,提供强大的调试支持。
  6. 可扩展性

    • 开放源代码,允许开发者自定义或扩展编译器的功能。
    • 支持插件,可用于增强编译过程或添加新的功能。

应用场景

GCC广泛应用于软件开发和系统编程领域,特别是在开源项目和Linux系统开发中。它是许多Linux发行版默认的编译器,用于编译Linux内核、GNU操作系统和其他大量的应用程序。

安装与使用

  • 在Linux系统中,GCC通常可以通过包管理器(如apt、yum等)安装。
  • 在Windows上,GCC可以通过MinGW(Minimalist GNU for Windows)或Cygwin等工具获得。
  • 在macOS上,可以通过Homebrew或Xcode的命令行工具来安装GCC。

GCC不仅仅是一个编译器,它还是一个强大的工具,对于软件开发和计算机科学教育来说至关重要。由于其开源和免费的特性,GCC对编程社区的贡献不可估量,是推动软件创新和教育普及的重要工具。

c11需要gcc版本 > 4.8.5

查看版本

gcc -v
image-20240417191223707

gcc工作流程

image-20240417191520664

GCC(GNU Compiler Collection)的工作流程涵盖了将源代码转换为可执行文件的多个阶段。这些阶段依次是预处理、编译、汇编和链接,每个阶段都承担着特定的任务,共同完成从源代码到可执行程序的转换。

  1. 预处理阶段(Preprocessing)
  • 任务:预处理器处理源代码文件中以#开头的指令。这包括宏定义的展开、文件包含指令的处理(如#include)、条件编译指令(如#ifdef, #ifndef, #endif)的处理等。
  • 结果:输出的结果是“展开”的源代码,已经插入了所有包含的文件内容,展开了所有宏定义,移除了所有条件不满足的代码块,此外还处理了编译器指令和特定的注释等。
  1. 编译阶段(Compilation)
  • 任务:编译器将预处理后的源代码转换成汇编语言。在这个阶段,编译器进行词法分析、语法分析、语义分析和优化。编译器检查代码的语法错误,分析变量和函数的使用情况,以及执行代码优化以提高程序的运行效率和减少内存占用。
  • 结果:生成的是汇编语言代码,对应于平台的机器指令集。
  1. 汇编阶段(Assembly)
  • 任务:汇编器将汇编语言转换为机器语言,生成目标代码。汇编语言是一种低级语言,比源代码更接近于机器代码,但仍然是人类可读的格式。
  • 结果:输出的是目标文件(通常是.o.obj文件),这些文件包含了机器语言代码但尚未解析外部引用。
  1. 链接阶段(Linking)
  • 任务:链接器处理一个或多个目标文件,并将它们与库(可能是动态的或静态的)合并,解析外部引用,生成最终的可执行文件。在这个阶段,链接器也处理符号解析、地址和偏移量分配等任务。
  • 结果:生成的是可执行文件(在Unix-like系统中通常无扩展名,在Windows中为.exe文件),这些文件包含了可以被操作系统载入内存并执行的所有机器指令。

示例

假设你有一个名为hello.c的C语言程序,整个GCC编译和链接的命令行可以简化为:

gcc -o hello hello.c

这条命令会自动执行上述所有阶段,从hello.c生成可执行文件hello。如果你想观察或控制中间过程,可以使用额外的GCC选项来单独执行各个阶段,例如:

gcc -E hello.c -o hello.i   # 只运行预处理,输出预处理后的文件hello.i
gcc -S hello.c              # 生成汇编代码hello.s
gcc -c hello.c              # 生成目标文件hello.o
gcc hello.o -o hello        # 将目标文件链接成最终的可执行文件

GCC的这种工作流程允许开发者对编译过程有更细致的控制,同时也支持跨平台开发,因为GCC可用于多种操作系统平台上。

gcc常用参数选项

GCC(GNU Compiler Collection)提供了许多命令行参数,这些参数允许开发者定制编译过程、优化生成的代码、指定特定的编译器行为等。下面列出了一些GCC中最常用的参数选项:

基本编译选项

  • -c

    • 编译源代码到目标文件,不进行链接。
    • 例如:gcc -c program.c 生成 program.o
  • -o output

    • 指定生成的输出文件的名称。
    • 例如:gcc program.c -o program 生成一个名为 program 的可执行文件。
  • -g

    • 生成调试信息,方便使用GDB等调试工具进行调试。
    • 例如:gcc -g program.c -o program

优化选项

  • -O, -O1, -O2, -O3

    • 设置优化级别:
      • -O0(默认):不进行优化。
      • -O1:进行基本优化。
      • -O2:进行进一步优化,包括增加编译时间的优化。
      • -O3:启用更多的优化,包括 -O2 所有的优化以及一些额外的优化来提升性能。
    • 例如:gcc -O2 program.c -o program
  • -Os

    • 优化生成的代码,使其占用的空间尽可能小。
    • 例如:gcc -Os program.c -o program

警告控制选项

  • -Wall

    • 开启几乎所有的警告信息。
    • 例如:gcc -Wall program.c -o program
  • -Wextra

    • 开启额外的警告信息,比 -Wall 更严格。
    • 例如:gcc -Wall -Wextra program.c -o program

链接选项

  • -l

    • 链接时指定库名。
    • 例如:gcc program.c -lm -o program 链接数学库 libm
  • -L

    • 指定库文件搜索路径。
    • 例如:gcc program.c -L/home/user/mylibs -lm -o program

预处理选项

  • -Dmacro

    • 定义宏。
    • 例如:gcc -DDEBUG program.c -o program 在编译时定义 DEBUG 宏。
  • -I

    • 指定包含文件(头文件)的搜索路径。
    • 例如:gcc -I/home/user/myheaders program.c -o program

其他有用的选项

  • -std=cXX

    • 指定使用特定的C语言标准进行编译,如 c99c11c17 等。
    • 例如:gcc -std=c11 program.c -o program 使用C11标准编译。
  • -pedantic

    • 要求GCC严格遵守ISO C和ISO C++标准,禁用非标准扩展。
    • 例如:gcc -pedantic program.c -o program
  • -s

    • 在生成最终的可执行文件时去除所有符号信息,用于减少可执行文件的大小。
    • 例如:gcc -s program.c -o program

这些选项只是GCC提供的众多参数中的一部分,但它们是最常用的一些,覆盖了大部分常规需求。你可以结合使用这些选项来控制GCC的行为,优化程序的性能,或者调整程序的编译过程。要了解更多详细的编译选项,可以查阅GCC官方文档或使用 man gcc 命令获取帮助。

image-20240417192648646 image-20240417200507644
gcc test.c -E -o test.i
#include <stdio.h>int main() {int a = 10;
#ifdef DEBUGprintf("我是一个dccc\n");
#endiffor (int i = 0; i < 3; i++) {printf("hello gcc\n");}return 0;
}
daic@daic:~/Linux/lesson03$ gcc test.c -o test -D DEBUG
daic@daic:~/Linux/lesson03$ ./test 
我是一个dccc
hello gcc
hello gcc
hello gcc
daic@daic:~/Linux/lesson03$ gcc test.c -o test -D DEBUG -Wall
test.c: In function ‘main’:
test.c:5:9: warning: unused variable ‘a’ [-Wunused-variable]int a = 10;^

gcc和g++区别

GCC(GNU Compiler Collection)包含了多个前端编译器,用于处理不同编程语言的编译任务。gccg++ 是这个集合中最常用的两个命令,它们分别用于编译C和C++程序。虽然这两个工具在很多方面相似,但它们在处理C和C++代码时有一些关键的区别和特定的用法。

1. 基本区别

  • gcc

    • 通常用于编译C程序。
    • 默认情况下,它将用作C编译器。
    • 如果没有特别指定,它将尝试以C语言的标准来编译源代码文件。
  • g++

    • 专门用于编译C++程序。
    • 自动将C++库链接到程序中,包括标准模板库(STL)。
    • 默认情况下,将用作C++编译器。
  1. 链接库的不同
  • 当编译C++程序时,g++ 会自动链接C++标准库(如libstdc++)。这意味着使用g++编译器,用户不需要显式指定运行时库,而使用gcc编译C++程序时,可能需要手动添加 -lstdc++ 选项来链接C++库。
  1. 处理C++的特性
  • g++对C++的支持更全面,包括对模板的处理以及C++的名称修饰(name mangling)。这些特性在用gcc编译C++代码时可能不会完全支持,或者需要额外的参数来正确处理。
  1. 文件扩展名的敏感性
  • gcc根据文件扩展名判断如何编译文件。例如,它会将.c文件视为C程序,.cpp.cc文件视为C++程序。根据文件类型的不同,gcc可能需要指定语言标准来正确编译。
  • g++默认将所有文件视为C++文件,除非另有指定。
  1. 编译C文件的行为
  • 你可以使用g++来编译C文件。在这种情况下,g++将C代码视为C++代码的一部分,这通常是安全的,因为C是C++的一个子集。然而,某些严格的C代码在C++编译器下可能会因为语法或语义差异而出现编译错误。

示例

  • 使用gcc编译C++代码时需要链接C++库:

    gcc some_code.cpp -lstdc++ -o some_code
    
  • 使用g++编译相同的C++代码,不需要手动链接C++库:

    g++ some_code.cpp -o some_code
    

结论

虽然gccg++都是GCC的一部分,并且都可以用来编译C和C++代码,但是它们在默认行为和链接库方面有所不同。一般来说,推荐使用g++编译C++代码,而gcc则用于C代码,这样可以确保编译过程的顺利进行和程序的正确链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/626630.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我们一起看看《看漫画学C++》中如何介绍的字符串的用法

C中的字符串使用的是 std::string 类型&#xff0c;它是C标准库中提供的字符串类&#xff0c;提供了丰富的字符串操作方法。下面是关于C字符串的一些常用用法&#xff1a; 字符串拼接 字符串查找 字符串追加 购书地址&#xff1a;https://item.jd.com/14418856.html

网工交换基础——MUX VLAN

前言&#xff1a; MUX VLAN&#xff08;Multiplex VLAN&#xff0c;多复用VLAN&#xff09;提供了一种通过VLAN进行网络资源控制的机制。例如&#xff0c;在企业网络中&#xff0c;企业员工和企业客户可以访问企业的服务器。对于企业来说&#xff0c;希望企业内部员工之…

c++的学习之路:24、 二叉搜索树概念

摘要 本章主要是讲一下二叉搜索树的实现 目录 摘要 一、二叉搜索树概念 二、 二叉搜索树操作 1、二叉搜索树的查找 2、二叉搜索树的插入 3、二叉搜索树的删除 三、二叉搜索树的实现 1、插入 2、中序遍历 3、删除 4、查找 四、二叉搜索树的递归实现 1、插入 2、删…

2024年机电工程与航天航空技术国际研讨会(ISMEEAT2024)

2024年机电工程与航天航空技术国际研讨会&#xff08;ISMEEAT2024) 会议简介 会议委员会很高兴邀请您参加在上海举行的2024国际机电工程与航空航天技术研讨会&#xff08;ISMEEAT2024&#xff09;。ISMEEAT2024为研究人员提供了一个创新的环境&#xff0c;展示他们的新研究和…

Pygame经典游戏:坦克大战TankWar+五子棋人机对弈(安排!!)

Python108款&#xff0c;小游戏集合&#xff0c;总有一个是你想要的 中国象棋 像素鸟 五子棋 24点小游戏 贪吃蛇 扫雷 俄罗斯方块 魂斗罗 消消乐 坦克大战 外星人入侵 汤姆猫 斗地主 乒乓球 推箱子 植物大战僵尸 围棋 超级玛丽 飞机大战 迷宫 滑雪 吃豆人…等等&#xff08;…

postman汉化

一、postman历史版本下载&#xff1a;Postman 10.24.16 Download for Windows / Old Versions / FileHorse.comhttps://www.filehorse.com/download-postman/old-versions/ 二、汉化包下载&#xff1a; Releases hlmd/Postman-cn GitHubPostman汉化中文版. Contribute to h…

Python文件操作大全

1 文件操作 1.1 文件打开与关闭 1.1.1 打开文件 在Python中&#xff0c;你可以使用 open() 函数来打开文件。以下是一个简单的例子&#xff1a; # 打开文件&#xff08;默认为只读模式&#xff09; file_path example.txt with open(file_path, r) as file:# 执行文件操作…

CTFHUB-技能树-Web前置技能-文件上传(无验证,JS前端验证,前端验证)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;无验证&#xff0c;JS前端验证&#xff0c;前端验证—.htaccess&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;无验证&#xff0c;JS前端验证&#xff0c;前端验证—.htaccess&#xff09;文件上传无验…

机器学习引领金融革命:重塑金融服务领域新格局,开启智能化新篇章

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

Oracle11.2.0.1,(CVE-2012-1675)漏洞解决方案

1.进入容器停止监听 docker exec -it -u 0 oracle11g bash su - oracle lsnrctl stop listener2.找到监听配置文件位置&#xff0c;修改监听文件 echo $ORACLE_HOMEvi network/admin/listener.ora #在文件底部添加 SECURE_REGISTER_LISTENER (IPC) #启动监听 lsnrctl start …

angular node版本问题导致运行出错时应该怎么处理

如下图所示&#xff1a; 处理方式如下&#xff1a; package.json中start跟build中添加&#xff1a;SET NODE_OPTIONS--openssl-legacy-provider即可

数据结构:打造高效的通讯录项目

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;http://t.csdnimg.cn/oHJAK&#xff08;数据结构与算法&#xff09; 小新的主页&#xff1a;编程版小新-CSDN博客 …