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 DEBUG
    printf("我是一个dccc\n");
#endif
    for (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.mfbz.cn/a/551886.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CMEF | 澳鹏Appen精彩亮相第89届中国国际医疗器械博览会

4月14日&#xff0c;为期四天的第89届中国国际医疗器械博览会&#xff08;CMEF&#xff09;盛大收官。如今&#xff0c;人们的健康需求在人口老龄化等一系列因素的影响下持续增长&#xff0c;这意味着卫生系统也面对着更多具有复杂健康需求的患者。信息化、数字化、智能化已经成…

Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码

Java语言开发的AI智慧导诊系统源码springbootredis 3D互联网智导诊系统源码 智慧导诊解决盲目就诊问题&#xff0c;减轻分诊工作压力。降低挂错号比例&#xff0c;优化就诊流程&#xff0c;有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位&#xff0c;了解对应…

1.总结串口的发送和接收功能使用到的函数2.总结DMA的作用,和DMA+空闲中断的使用方式3.使用PWM+ADC光敏电阻完成光控灯的实验

1.总结串口的发送和接收功能使用到的函数 串口发送函数&#xff1a;HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) UART_HandleTypeDef *huart&#xff1a;指定要使用的串口 const uint8_t *pData&…

计算机中的小数表示

文章目录 前言整数表示的缺陷定点小数定点小数加法乘法运算 浮点数IEEE754浮点数标准移码阶码的移码表示 IEEE754中的特殊点两个0非规格化数字正常浮点数无穷大NaN 浮点数简单举例浮点数一些其余特性浮点数计算不符合结合律浮点数舍入规则浮点数与整数之间的相互转换 总结 前言…

条形码与二维码的优缺点分析

条形码和二维码在我们的日常生活和工业应用中无处不在&#xff0c;广泛应用于各类商品、物流、防伪等各个领域&#xff0c;它们可以帮助我们快速识别产品、跟踪货物、管理库存、验证身份、获取信息等。条形码和二维码凭借着便捷、低成本、精准等独特的优势&#xff0c;应用领域…

(C语言入门)复合类型、内存管理

目录 复合类型&#xff08;自定义类型&#xff09; 概述&#xff1a; 结构体变量的定义和初始化&#xff1a; 结构体成员的使用&#xff1a; 结构体做函数参数&#xff1a; 结构体值传参&#xff1a; 结构体地址传参&#xff1a; 共用体&#xff08;联合体&#xff09;&…

前端开发攻略---实现与ChatGPT同款光标闪烁打字效果。

1、演示 2、实现代码 <!DOCTYPE html> <html lang"ch-ZN"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"widt…

基于R语言实现的beta二项回归模型【理解与实现】

本实验&#xff0c;创建一组使用二项分布模拟的数据&#xff08;不带额外的随机性&#xff09;&#xff0c;和另一组使用Beta二项分布模拟的数据&#xff08;引入了随机成功概率 p&#xff0c;从而增加了数据的离散性。 现在假设我们站在上帝视角&#xff0c;有两组不知道分布…

网工交换基础——MUX VLAN

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

谷粒商城part3——快速开发篇

这里是过来人的学习建议&#xff1a; 1、如有条件电脑内存至少16G起步&#xff0c;条件进一步加个屏幕&#xff0c;条件更进一步租一台至少4G内存的X86架构云服务器&#xff0c;所有部署的东西全扔云服务器上 2、P16&#xff0c;P17没法搭起来的建议照着rerenfast的github上的教…

Python革命:如何利用AI数据分析引领人工智能的未来

在人工智能迅速发展的今天&#xff0c;Python语言已经成为了推动AI领域发展的一大利器。作为一种高级编程语言&#xff0c;Python以其简洁的语法和强大的功能&#xff0c;为AI数据分析提供了强有力的支持&#xff0c;帮助开启了人工智能的新时代。 Python的核心优势 Python的最…

FreeRTOS学习 -- 中断配置

一、什么是中断 中断时微控制器一个很常见的特性&#xff0c;中断是由硬件产生&#xff0c;当中断产生以后CPU就会中断当前的流程而去处理中断服务&#xff0c;Cortex-M内核的MCU提供了一个用于中断管理的嵌套向量中断控制器&#xff08;NVIC&#xff09;。 二、中断优先级分…

区块链安全应用----压力测试

通过Caliper进行压力测试程序 1.环境配置 第一步. 配置基本环境 部署Caliper的计算机需要有外网权限&#xff1b;操作系统版本需要满足以下要求&#xff1a;Ubuntu > 16.04、CentOS > 7或MacOS > 10.14&#xff1b;部署Caliper的计算机需要安装有以下软件&#xff…

作业4.17

1.总结串口的发送和接收功能使用到的函数 发送&#xff1a; HAL_StatusTypeDef HAL_UART_Transmit( UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout ) 接受&#xff1a; HAL_StatusTypeDef HAL_UART_Receive_IT( UART_HandleTypeDef *…

刀具表面上的微结构

刀具表面微结构通常指在刀具表面对特定功能设计的微观纹理&#xff0c;这些纹理可以是沟槽、凹坑、凸起或任何其他形式的微观图案。这些微结构的设计和应用是为了改善刀具的切削性能&#xff0c;减少切削力和切削温度&#xff0c;提高切削效率和精度&#xff0c;同时降低切削液…

Sa-Token使用经验

官方文档;Sa-Token Sa-Token 介绍 Sa-Token 是一个轻量级 Java 权限认证框架&#xff0c;主要解决&#xff1a;登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。 Sa-Token 旨在以简单、优雅的方式完成系统的权限认证部分…

第十六篇:springboot案例

文章目录 一、准备工作1.1 需求说明1.2 环境搭建1.3 开发规范1.4 思路 二、部门管理2.1 查询部门2.2 删除部门2.3 新增部门2.4 修改部门2.5 RequestMapping 三、员工管理3.1 分页查询3.2 删除员工3.3 新增员工3.3.1 新增员工3.3.2 文件上传 3.4 修改员工3.4.1 页面回显3.4.2 修…

C++ stl容器list的底层模拟实现

目录 前言&#xff1a; 1.创建节点 2.普通迭代器的封装 3.反向迭代器的封装 为什么要对正向迭代器进行封装&#xff1f; 4.const迭代器 5.构造函数 6.拷贝构造 7.赋值重载 8.insert 9.erase 10.析构 11.头插头删&#xff0c;尾插尾删 12.完整代码简单测试 总结&…

刀具刃口钝化

​刀具刃口钝化是指在刀具制作过程中&#xff0c;通过一系列的加工步骤使刀具刃口表面变得光滑、平整&#xff0c;去除因磨削加工造成的微观缺口&#xff0c;以提高刀具的切削性能和寿命。这一过程对于保障刀具的稳定性和精度至关重要&#xff0c;尤其是在高速切削和高精度加工…

Leetcode刷题之合并两个有序数组

Leetcode刷题之合并两个有序数组 一、题目描述二、题目解析 一、题目描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数…