讲师中心 微信公众号
AI工具推荐 视频效率加速

c++ 编译和链接过程 c++代码如何变成可执行文件

阿涛吖_2315

阿涛吖_2315

发布时间:2026-03-18 20:52:31

|

411人浏览过

|

来源于php中文网

原创

C++构建分编译(预处理、编译、汇编)和链接两阶段:预处理展开宏与头文件,编译生成汇编,汇编生成目标文件(.o),链接合并多个.o及库并解析符号地址;常见错误如undefined reference源于漏链接或依赖顺序不当,-c、-E、-S等选项可控制流程,依赖管理需构建系统支持。

c++ 编译和链接过程 c++代码如何变成可执行文件

编译阶段:预处理、编译、汇编三步走,g++ 默认连着干

你写的 .cpp 文件不是直接变机器码的,中间要过三道关。预处理展开 #include 和 #define,编译器把 C++ 语法翻译成汇编指令,最后汇编器把汇编转成目标文件(.o 或 .obj)。g++ 默认一步到位,但加 -c 就停在目标文件这步:g++ -c main.cpp 生成 main.o,不生成可执行文件。

常见错误现象:undefined reference to `main' 这类链接错误,其实常是因为漏了 -c 之后没继续链接,或者多个 .o 没一起喂给链接器。

  • 预处理用 g++ -E main.cpp 看展开后长啥样,特别适合查宏定义没生效的问题
  • g++ -S main.cpp 只到汇编,生成 main.s,能确认编译器是否真按你预期优化或内联
  • 不同源文件各自 -c 生成 .o,是增量编译的基础,改一个文件不用全重编

链接阶段:把多个 .o 和库拼成一个 exe 或 a.out

目标文件里有符号(比如函数名、全局变量),但地址全是“占位符”。链接器负责填上真实内存地址,并解决跨文件引用。你写 std::cout,实际调用的是 libstdc++ 里的实现,链接时得把那部分代码也塞进来。

典型卡点:undefined reference to `foo()' 表示链接器在所有输入文件和库里都找不到 foo 的定义;multiple definition of `bar' 是同一个符号在多个 .o 里都定义了(比如头文件里写了非 inline 函数实现)。

立即学习“C++免费学习笔记(深入)”;

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • 手动链接:把所有 .o 一次性传给 g++,比如 g++ main.o utils.o -o program,g++ 此时只做链接,不重新编译
  • 静态库是 .a 文件,本质是一堆 .o 打包,链接时用 -L/path/to/lib -lmylib;动态库是 .so(Linux)或 .dll(Windows),运行时才加载
  • 链接顺序有影响:依赖别人的模块放前面,被依赖的放后面,否则可能报未定义——g++ app.o -lm 对,g++ -lm app.o 在老版本 ld 上可能失败

g++ 一条命令背后的隐式步骤和开关控制

你以为 g++ main.cpp -o program 是“编译并链接”,其实它悄悄调了预处理器、编译器、汇编器、链接器四道程序。你可以用 -v 看它到底执行了哪些命令,路径、参数、默认库路径全打出来,调试构建问题时非常管用。

容易忽略的细节:C++ 标准库不是自动“免费”链接的。比如用了 std::thread 却没加 -pthread,Linux 下会链接失败;用了 std::filesystem(C++17),得显式加 -lstdc++fs。

  • -x c++ 强制把后缀非 .cpp 的文件当 C++ 处理,比如编译 main.cc 时 g++ 有时会误判为 C
  • -nostdlib 完全不链标准启动代码和库,裸机或嵌入式开发才用,日常别碰
  • -Wl,--no-as-needed 让链接器不跳过看起来“没用”的库,某些依赖间接调用的场景需要

为什么改了头文件却没重新编译?依赖关系谁在管

编译器自己不管依赖,g++ 生成的 .o 也不记录“我依赖哪些头文件”。所以你改了 utils.h,如果构建系统没告诉它 main.o 要重做,就会用旧的目标文件,导致行为不一致。

Makefile 或 CMake 的核心任务之一,就是维护这种依赖关系。C++ 编译器可以通过 -M 系列选项生成依赖规则:g++ -MM main.cpp 输出 main.o: main.cpp utils.h 这样的行,供 Make 读取。

  • -M 输出所有依赖(含系统头),-MM 只输出用户头文件,更实用
  • CMake 默认开启依赖扫描,但如果你手写 add_executable 时漏了某个 .h 文件,它不会自动感知——头文件不参与构建规则生成,除非你显式 target_sources(... PRIVATE ...)
  • IDE(如 VS Code + CMake Tools)有时缓存旧的依赖图,改完头文件后清一下 build/ 目录再生成,比猜“为啥没生效”快得多
C++ 构建过程里最麻烦的从来不是语法转换,而是符号怎么找、什么时候找、从哪找——链接时报错往往离真正出问题的代码隔了两层抽象,而依赖管理又藏在构建系统背后,看不见摸不着。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

相关专题

更多
typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

313

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

619

2023.10.11

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

4185

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

1730

2025.09.18

c++ 全局变量
c++ 全局变量

本专题整合了c++全局变量的使用、定义、作用域等等内容,阅读专题下面的文章了解更多详细内容。

199

2026.03.17

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

5307

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2348

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

543

2025.12.01

C++运算符基础入门
C++运算符基础入门

本专题详细讲解了C++运算符的类型、语法与使用方法,涵盖算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、条件运算符及其他特殊运算符,并通过代码示例解析优先级与结合性。

0

2026.10.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn